POJ - 3463 Sightseeing 次短路和最短路数目

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 10000 + 7;
typedef long long LL;
struct Edge{
   int to,next;
   LL val;
}edge[maxn];
struct Node{
   int p,flag;
   LL len;
   bool operator < (const Node &another)const{
        return len > another.len;
   }
   Node(int a,int b, LL c):p(a),flag(b),len(c) {}
};
int n,m,head[maxn],tot,s,t;
LL dist[maxn][2],num[maxn][2];
bool vis[maxn][2];
void addEdge(int a,int b,LL c){
   edge[tot].to = b;edge[tot].val = c;edge[tot].next = head[a];head[a] = tot++;
}
void Dijkstra(int s){
    memset(dist,INF,sizeof(dist));
    dist[s][0] = 0;
    num[s][0] = 1;
    priority_queue<Node>que;
    que.push(Node(s,0,0));
    while(!que.empty()){
        Node p = que.top();
        que.pop();
        if(vis[p.p][p.flag])continue;
        vis[p.p][p.flag] = 1;
        for(int i = head[p.p];~i;i = edge[i].next){
            LL d = p.len + edge[i].val;
            if(!vis[edge[i].to][0]&&dist[edge[i].to][0] > d){//小于最短路
                dist[edge[i].to][1] = dist[edge[i].to][0];//原来最短路变为次短路
                num[edge[i].to][1] = num[edge[i].to][0];
                que.push(Node(edge[i].to,1,dist[edge[i].to][1]));

                dist[edge[i].to][0] = d;//更新最短路
                num[edge[i].to][0] = num[p.p][p.flag];
                que.push(Node(edge[i].to,0,d));
            }
            else if(dist[edge[i].to][0] == d){//等于最短路
                num[edge[i].to][0]+=num[p.p][p.flag];
            }
            else if(!vis[edge[i].to][1]&&dist[edge[i].to][1] > d&&dist[edge[i].to][0] < d){//小于次短路
                 dist[edge[i].to][1] = d;
                 num[edge[i].to][1]=num[p.p][p.flag];
            }
            else if(dist[edge[i].to][1] == d){//等于次短路
                 num[edge[i].to][1]+=num[p.p][p.flag];
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        tot = 0;
        memset(vis,0,sizeof(vis));
        memset(num,0,sizeof(num));
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for(int i = 0;i<m;i++){
             int a,b,v;
             scanf("%d%d%lld",&a,&b,&v);
             addEdge(a,b,v);
        }
        scanf("%d%d",&s,&t);
        Dijkstra(s);
        LL sum = 0;
        if(dist[t][1] == dist[t][0] + 1)sum+=num[t][1];
        sum+=num[t][0];
        printf("%lld\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40772692/article/details/83903049