题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805051153825792
题意:给定n个地点,m条边以及边的信息,给出起点s,终点d,求s到d的最快距离,不唯一时取距离最短的,还要求s到d的最短距离,不唯一时取经过结点数最少的,若这两条路线重合,输出一条即可。
思路:两次dijkstra算法,第一次的两个维度是时间tim,距离len,用pre1记录路径; 第二次的两个维度是距离len,经过结点数num,用pre2记录路径。为了便于比较两条路径是否一致,可将其存在vector中,直接用‘==’判断即可,然后按照要求输出(代码看着挺长,其实两次dijkstra差不多)。
AC代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=505; 5 const int inf=0x3f3f3f3f; 6 int n,m,s,d; 7 int a[maxn][maxn],b[maxn][maxn],tim[maxn],len[maxn],num[maxn],vis1[maxn],vis2[maxn],pre1[maxn],pre2[maxn]; 8 vector<int> v1,v2; 9 10 void dijkstra1(){ 11 len[s]=tim[s]=0; 12 for(int i=0;i<n;++i){ 13 int k,Min=inf; 14 for(int j=0;j<n;++j) 15 if(!vis1[j]&&tim[j]<Min) 16 k=j,Min=tim[j]; 17 if(Min==inf) break; 18 vis1[k]=1; 19 for(int j=0;j<n;++j) 20 if(!vis1[j]&&tim[j]>tim[k]+b[k][j]){ 21 tim[j]=tim[k]+b[k][j]; 22 len[j]=len[k]+a[k][j]; 23 pre1[j]=k; 24 } 25 else if(!vis1[j]&&tim[j]==tim[k]+b[k][j]&&len[j]>len[k]+a[k][j]){ 26 len[j]=len[k]+a[k][j]; 27 pre1[j]=k; 28 } 29 } 30 } 31 32 void dijkstra2(){ 33 len[s]=0,num[s]=1,pre2[s]=-1; 34 for(int i=0;i<n;++i){ 35 int k,Min=inf; 36 for(int j=0;j<n;++j) 37 if(!vis2[j]&&len[j]<Min) 38 k=j,Min=len[j]; 39 if(Min==inf) break; 40 vis2[k]=1; 41 for(int j=0;j<n;++j) 42 if(!vis2[j]&&len[j]>len[k]+a[k][j]){ 43 len[j]=len[k]+a[k][j]; 44 num[j]=num[k]+1; 45 pre2[j]=k; 46 } 47 else if(!vis2[j]&&len[j]==len[k]+a[k][j]&&num[j]>num[k]+1){ 48 num[j]=num[k]+1; 49 pre2[j]=k; 50 } 51 } 52 } 53 54 void getv1(){ 55 int p=d; 56 while(p!=-1){ 57 v1.push_back(p); 58 p=pre1[p]; 59 } 60 } 61 62 void getv2(){ 63 int p=d; 64 while(p!=-1){ 65 v2.push_back(p); 66 p=pre2[p]; 67 } 68 } 69 70 int main() 71 { 72 scanf("%d%d",&n,&m); 73 memset(a,0x3f,sizeof(a)); 74 memset(b,0x3f,sizeof(b)); 75 for(int i=0;i<n;++i) 76 tim[i]=len[i]=inf,pre1[i]=-1; 77 for(int i=0;i<m;++i){ 78 int t1,t2,flag,l,t; 79 scanf("%d%d%d%d%d",&t1,&t2,&flag,&l,&t); 80 a[t1][t2]=l,b[t1][t2]=t; 81 if(!flag) 82 a[t2][t1]=l,b[t2][t1]=t; 83 } 84 scanf("%d%d",&s,&d); 85 dijkstra1(); 86 getv1(); 87 for(int i=0;i<n;++i) 88 len[i]=num[i]=inf,pre2[i]=-1; 89 dijkstra2(); 90 getv2(); 91 if(v1==v2){ 92 printf("Time = %d; Distance = %d: %d",tim[d],len[d],s); 93 for(int i=v1.size()-2;i>=0;--i) 94 printf(" => %d",v1[i]); 95 } 96 else{ 97 printf("Time = %d: %d",tim[d],s); 98 for(int i=v1.size()-2;i>=0;--i) 99 printf(" => %d",v1[i]); 100 printf(" "); 101 printf("Distance = %d: %d",len[d],s); 102 for(int i=v2.size()-2;i>=0;--i) 103 printf(" => %d",v2[i]); 104 } 105 return 0; 106 }