PAT 1111 Online Map
dijstra经典题
相同路径取用时最短
相同用时取节点数最少
但注意用vector存储节点时,每次更新需要清空之前的值,保存最新的路径。
参考自:https://www.liuchuo.net/archives/2407
#include <iostream> #include<cstdio> #include<vector> #define MAX 99999999 using namespace std; int n,m,s,t; int dis[505],cosd[505],vis[505],cost[505],num[505]; struct Edge{ int next; int dis; int time; }; vector<Edge> ed[505]; vector<int> ansd,anst,path; vector<int> pred[505],pret[505];//最短路前缀数组 void dfsd(int v){ ansd.push_back(v); if(v==s) return; dfsd(pred[v][0]); } void dfst(int v){ anst.push_back(v); if(v==s) return; dfst(pret[v][0]); } void print(vector<int> v){ for(int i=v.size()-1;i>=0;i--){ if(i==v.size()-1) printf("%d",v[i]); else printf(" -> %d",v[i]); } printf("\n"); } int main(int argc, char** argv) { scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ int v1,v2,tag,length,time; scanf("%d %d %d %d %d",&v1,&v2,&tag,&length,&time); Edge tmp; tmp.next=v2;tmp.dis=length;tmp.time=time; ed[v1].push_back(tmp); if(!tag){ Edge tmp; tmp.next=v1;tmp.dis=length;tmp.time=time; ed[v2].push_back(tmp); } //0为双向 } scanf("%d%d",&s,&t); for(int i=0;i<n;i++){ dis[i]=MAX; vis[i]=0; cosd[i]=MAX; cost[i]=MAX; num[i]=MAX; } dis[s]=0,cosd[s]=0; num[s]=0,cost[s]=0; for(int i=0;i<n;i++){ int minv=MAX,ind=-1; for(int j=0;j<n;j++){ if(!vis[j]){ if(dis[j]<minv){ minv=dis[j]; ind=j; } } } vis[ind]=1; for(int j=0;j<ed[ind].size();j++){ int tmp=ed[ind][j].next; if(!vis[tmp]){ if(dis[tmp]>dis[ind]+ed[ind][j].dis){ dis[tmp]=dis[ind]+ed[ind][j].dis; cosd[tmp]=cosd[ind]+ed[ind][j].time; pred[tmp].clear(); pred[tmp].push_back(ind);//前缀数组 }else if(dis[tmp]==dis[ind]+ed[ind][j].dis&&cosd[tmp]>cosd[ind]+ed[ind][j].time){ cosd[tmp]=cosd[ind]+ed[ind][j].time;// pred[tmp].clear(); pred[tmp].push_back(ind); } } } } dfsd(t); //时间最短 fill(vis,vis+505,0); for(int i=0;i<n;i++){ int minv=MAX,ind=-1; for(int j=0;j<n;j++){ if(!vis[j]){ if(cost[j]<minv){ minv=cost[j]; ind=j; } } } vis[ind]=1; for(int j=0;j<ed[ind].size();j++){ int tmp=ed[ind][j].next; if(!vis[tmp]){ if(cost[tmp]>cost[ind]+ed[ind][j].time){ cost[tmp]=cost[ind]+ed[ind][j].time; num[tmp]=num[ind]+1;// pret[tmp].clear(); pret[tmp].push_back(ind);//前缀数组 }else if(cost[tmp]==cost[ind]+ed[ind][j].time&&num[tmp]>num[ind]+1){ num[tmp]=num[ind]+1; pret[tmp].clear(); pret[tmp].push_back(ind);//每次弹出之前的值,更新 } } } } dfst(t); if(ansd==anst){ printf("Distance = %d; Time = %d: ",dis[t],cost[t]); print(anst); }else{ printf("Distance = %d: ",dis[t]); print(ansd); printf("Time = %d: ",cost[t]); print(anst); } return 0; }