观光(统计最短路,次短路条数)

在这里插入图片描述

思路:问最短路和次短路的条数和,并且次短路只比最短路多1,我们在dijkstra时进行统计和更新,用dis[i][0]表示到i点的最短距离用dis[i][1]表示到i点的次短距离,用cnt[i][0]表示到i的最短路径的条数,用cnt[i][1]表示到i的次短路径条数,当我们到 i 点最短路需要更新时,那么原来到 i 的最短路就会变成次短路,先更新一下次短路的距离,此时到 i 次短路的条数也是就变成了之前到 i 的最短路条数,然后我们再更新最短路的距离,最短路的次数也更新,当我们发现和最短路距离相同则我们发现新的路径,只更新到该点的最短路条数,当我们发现此时可以更新次短路距离时,更新次短路距离和路径条数,当发现和次短路距离相同时则只更新次短路条数,

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
const int mod=100003;
const int N=2e5+5;
const int inf=0x7f7f7f7f;

int gcd(int a,int b)
{
    
    
    return b==0?a:gcd(b,a%b);
}
 
ll lcm(ll a,ll b)
{
    
    
    return a*(b/gcd(a,b));
}
 
template <class T>
void read(T &x)
{
    
    
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    
    
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
         write(x / 10);
    putchar('0' + x % 10);
}
ll qsm(int a,int b,int p)
{
    
    
    ll res=1%p;
    while(b)
    {
    
    
        if(b&1)
            res=res*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return res;
}
struct node
{
    
    
    int to,nex,w;
}edge[N];
struct Ver
{
    
    
    int ver,type,dist;
    bool operator> (const Ver &W)const
    {
    
    
        return dist>W.dist;
    }
};

int head[N],dis[N][2],cnt[N][2];
int tot,bcnt;
int n,m,S,T;
int vis[N][2];
void add(int u,int v,int w)
{
    
    
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].nex=head[u];
    head[u]=tot++;
}
int dij()
{
    
    
    memset(vis,0,sizeof vis);
    memset(cnt,0,sizeof cnt);
    memset(dis,inf,sizeof dis);
    cnt[S][0]=1;
    dis[S][0]=0;
    priority_queue<Ver,vector<Ver>,greater<Ver> > heap;
    heap.push({
    
    S,0,0});
    while(heap.size())
    {
    
    
        Ver now=heap.top();heap.pop();
        int distance=now.dist,type=now.type,ver=now.ver;
        int num=cnt[ver][type];
        if(vis[ver][type])continue;
        vis[ver][type]=1;
        for(int i=head[ver];~i;i=edge[i].nex)
        {
    
    
            int v=edge[i].to,w=edge[i].w;
            
            if(dis[v][0]>distance+w)
            {
    
    
                dis[v][1]=dis[v][0];
                cnt[v][1]=cnt[v][0];
                heap.push({
    
    v,1,dis[v][1]});
                dis[v][0]=distance+w;
                cnt[v][0]=num;
                heap.push({
    
    v,0,dis[v][0]});
            }
            else if(dis[v][0]==distance+w)
            {
    
    
                cnt[v][0]+=num;
            }
            else if(dis[v][1]>distance+w)
            {
    
    
                dis[v][1]=distance+w;
                cnt[v][1]=num;
                heap.push({
    
    v,1,dis[v][1]});
            }else if(dis[v][1]==distance+w)
            {
    
    
                cnt[v][1]+=num;
            }
        
        }
    }
    int res=cnt[T][0];
    if(dis[T][0]+1==dis[T][1])res+=cnt[T][1];
    
    return res;

}


int main()
{
    
    
  int t;
  scanf("%d",&t);
  while(t--)
  {
    
    

       scanf("%d%d",&n,&m);
       memset(head,-1,sizeof head);
       while(m--)
     {
    
    
      int a,b,c;
      scanf("%d%d%d",&a,&b,&c);
      add(a,b,c);
     }
     scanf("%d%d",&S,&T);
    
     printf("%d\n",dij());
 

  }
 

   return 0;

}


猜你喜欢

转载自blog.csdn.net/qq_43619680/article/details/113063593
今日推荐