pta l3-7(天梯地图)

题目链接: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("\n");
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 }

 

posted @ 2019-03-26 17:31  Frank__Chen  阅读(343)  评论(0编辑  收藏  举报