3463 Sightseeing 次短路和最短路數目
阿新 • • 發佈:2018-12-20
#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; }