题意:求最短路和比最短路长度多1的次短路的个数
本来想图(有)方(模)便(版)用spfa的,结果妹纸要我看看dijkstra怎么解....
写了三遍orz
Ver1.0:堆优化+邻接表,WA
1 //不能用堆优化+邻接表,因为需要处理dis[i][0]和dis[i][1]两套,如果都挤到一个堆里就乱套了 2 3 #include <iostream> 4 #include <cstdio> 5 #include <queue> 6 #include <cstring> 7 #include <vector> 8 using namespace std; 9 const int Ni = 10000; 10 const int INF = 1<<27; 11 struct node 12 { //eg[i].x eg[i].d i:start x:end d:distance 13 int x,d; 14 node(){} 15 node(int a,int b){x=a;d=b;} 16 bool operator < (const node & a) const //用于优先队列, 取距离原点最近的点 17 { 18 if(d==a.d) return x<a.x; 19 else return d > a.d; 20 } 21 }; 22 vector<node> eg[Ni]; 23 int dis[Ni][5],cnt[Ni][5],n,T; 24 25 void Dijkstra(int s) //1.比最短路短2.等于最短路3.长于最短路但短于次短路4.等于次短路 26 { 27 memset(dis,0,sizeof(dis)); 28 memset(cnt,0,sizeof(cnt)); 29 30 int i; 31 for(i=0;i<=n;i++) 32 { 33 dis[i][1]=INF; 34 dis[i][2]=INF; 35 } 36 dis[s][1]=0; 37 dis[s][2]=0; 38 priority_queue<node> q; //q:优先队列,用来取离原点最近的顶点 39 q.push(node(s,dis[s][1])); //初始只有一个原点自己 40 while(!q.empty()) 41 { 42 node x=q.top();q.pop(); 43 for(i=0;i<eg[x.x].size();i++) 44 { 45 node y=eg[x.x][i]; 46 if(dis[y.x][1]>x.d+y.d) //1 47 { 48 cnt[y.x][1]=1; 49 cnt[y.x][2]=1; 50 dis[y.x][2]=dis[y.x][1]; 51 dis[y.x][1]=x.d+y.d; 52 q.push(node(y.x,dis[y.x][1])); 53 } 54 else if (dis[y.x][1]==x.d+y.d) //2 55 { 56 cnt[y.x][1]++; 57 } 58 else if ((dis[y.x][1]<x.d+y.d)&&(x.d+y.d<dis[y.x][2])) //3 59 { 60 cnt[y.x][2]=1; 61 dis[y.x][2]=x.d+y.d; 62 } 63 else if (x.d+y.d==dis[y.x][2]) //4 64 { 65 cnt[y.x][2]++; 66 } 67 } 68 } 69 } 70 71 void debug() 72 { 73 cout<<"Debug only"<<endl; 74 for (int i=1;i<=n;i++) 75 printf("%d - %d %d - %d %d\n",i,dis[i][1],cnt[i][1],dis[i][2],cnt[i][2]); 76 cout<<ans1<<" "<<ans2<<endl; 77 78 } 79 80 int main() 81 { 82 scanf("%d",&T); 83 while (T--) 84 { 85 int a,b,d,m,k,st; 86 scanf("%d%d",&n,&m); 87 for(int i=0;i<=n;i++) eg[i].clear(); 88 while(m--) 89 { 90 scanf("%d%d%d",&a,&b,&d); 91 eg[a].push_back(node(b,d)); 92 } 93 scanf("%d %d",&k,&st); 94 Dijkstra(k); 95 96 debug1(); 97 98 int t1=dis[st][1],t2=dis[st][2],ans1=cnt[st][1],ans2; 99 if (t2-t1==1) 100 ans2=cnt[st][2]; 101 else ans2=0; 102 printf("%d\n",ans1+ans2); 103 } 104 105 return 0; 106 }