【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 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)