【PAT甲级】1111 Online Map (30分)(dijkstra+路径记录)

题意:

输入两个正整数N和M(N<=500,M<=N^2),分别代表点数和边数。接着输入M行每行包括一条边的两个结点(0~N-1),这条路的长度和通过这条路所需要的时间。接着输入两个整数表示起点和终点,输出路径最短的路,如果多条路路径最短输出其中通过时间最短的路,以及通过时间最短的路,如果通过时间最短的路有多条输出其中经过点个数最短的路,如果两条路相同,则合并输出。详见样例。

trick:

用邻接表存图,优先队列优化版本的dijkstra做,最后一个测试点会段错误,将数组开到25000以上后变为答案错误,实际上看似没有访问500~25000这一段数组,原因暂时不明,对于点少边多的图,可能用朴素写法效率较高,并且邻接表存图并不会占用太大空间,完全可以实现。

AAAAAccepted code:

  1 #define HAVE_STRUCT_TIMESPEC
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 int dis[507],tim[507];
  5 int e[507][507],w[507][507];
  6 int pre[507],timpre[507],weight[507],num[507];
  7 bool vis[507];
  8 vector<int>dispath,timpath;
  9 int s,t;
 10 void dfsdispath(int v){
 11     dispath.push_back(v);
 12     if(v==s)
 13         return ;
 14     dfsdispath(pre[v]);
 15 }
 16 void dfstimpath(int v){
 17     timpath.push_back(v);
 18     if(v==s)
 19         return ;
 20     dfstimpath(timpre[v]);
 21 }
 22 int main(){
 23     ios::sync_with_stdio(false);
 24     cin.tie(NULL);
 25     cout.tie(NULL);
 26     for(int i=0;i<500;++i)
 27         dis[i]=1e9+7,tim[i]=1e9+7,weight[i]=1e9+7;
 28     for(int i=0;i<500;++i)
 29         for(int j=0;j<500;++j)
 30             e[i][j]=w[i][j]=1e9+7;
 31     int n,m;
 32     cin>>n>>m;
 33     int u,v,flag,x,y;
 34     for(int i=0;i<m;++i){
 35         cin>>u>>v>>flag>>x>>y;
 36         e[u][v]=x;
 37         w[u][v]=y;
 38         if(!flag){
 39             e[v][u]=x;
 40             w[v][u]=y;
 41         }
 42     }
 43     cin>>s>>t;
 44     dis[s]=0;
 45     for(int i=0;i<n;++i){
 46         int u=-1,mn=1e9+7;
 47         for(int j=0;j<n;++j){
 48             if(!vis[j]&&dis[j]<mn){
 49                 u=j;
 50                 mn=dis[j];
 51             }
 52         }
 53         if(u==-1)
 54             break;
 55         vis[u]=1;
 56         for(int v=0;v<n;++v){
 57             if(!vis[v]&&e[u][v]<1e9+7){
 58                 if(e[u][v]+dis[u]<dis[v]){
 59                     dis[v]=e[u][v]+dis[u];
 60                     weight[v]=weight[u]+w[u][v];
 61                     pre[v]=u;
 62                 }
 63                 else if(e[u][v]+dis[u]==dis[v]&&weight[v]>weight[u]+w[u][v]){
 64                     weight[v]=weight[u]+w[u][v];
 65                     pre[v]=u;
 66                 }
 67             }
 68         }
 69     }
 70     dfsdispath(t);
 71     tim[s]=0;
 72     for(int i=0;i<500;++i)
 73         vis[i]=0;
 74     for(int i=0;i<n;++i){
 75         int u=-1,mn=1e9+7;
 76         for(int j=0;j<n;++j){
 77             if(!vis[j]&&mn>tim[j]){
 78                 u=j;
 79                 mn=tim[j];
 80             }
 81         }
 82         if(u==-1)
 83             break;
 84         vis[u]=1;
 85         for(int v=0;v<n;++v){
 86             if(!vis[v]&&w[u][v]<1e9+7){
 87                 if(w[u][v]+tim[u]<tim[v]){
 88                     tim[v]=w[u][v]+tim[u];
 89                     timpre[v]=u;
 90                     num[v]=num[u]+1;
 91                 }
 92                 else if(w[u][v]+tim[u]==tim[v]&&num[u]+1<num[v]){
 93                     timpre[v]=u;
 94                     num[v]=num[u]+1;
 95                 }
 96             }
 97         }
 98     }
 99     dfstimpath(t);
100     cout<<"Distance = "<<dis[t];
101     if(dispath==timpath)
102         cout<<"; Time = "<<tim[t]<<": ";
103     else{
104         cout<<": ";
105         for(int i=dispath.size()-1;i>=0;--i){
106             cout<<dispath[i];
107             if(i>0)
108                 cout<<" -> ";
109         }
110         cout<<"\nTime = "<<tim[t]<<": ";
111     }
112     for(int i=timpath.size()-1;i>=0;--i){
113         cout<<timpath[i];
114         if(i>0)
115             cout<<" -> ";
116     }
117     return 0;
118 }

 

posted @ 2020-02-10 20:47  sewage  阅读(294)  评论(0编辑  收藏  举报