直接采用Dijkstra算法
#include<iostream> #include<vector> #include<cstdio> using namespace std; const int INF=1000000; int dis[500][500],mindis[500],cost[500][500],mincost[500],pre[500];//从左至右依次表示【两个城市之间的距离】,【两个城市之间的最短距离】,【两个城市之间的花费】,【两个城市之间的最少花费】,【符合要求的直接前驱】 bool vis[500]={false}; vector<int> v[500]; int N,M,S,D; void Dijkstra(int S){ fill(mindis,mindis+500,INF); fill(mincost,mincost+500,INF); mindis[S]=0; mincost[S]=0; for(int i=0;i<N;i++){ int u=-1,MIN=INF; for(int j=0;j<N;j++){ if(vis[j]==false&&mindis[j]<MIN){ MIN=mindis[j]; u=j; } } if(u==-1)return; vis[u]=true; for(int i=0;i<v[u].size();i++){ int j=v[u][i]; if(vis[j]==false){ if(mindis[u]+dis[u][j]<mindis[j]){ mindis[j]=mindis[u]+dis[u][j]; mincost[j]=mincost[u]+cost[u][j]; pre[j]=u; } else if(mindis[u]+dis[u][j]==mindis[j]){ if(mincost[u]+cost[u][j]<mincost[j]){ mincost[j]=mincost[u]+cost[u][j]; pre[j]=u; } } } } } } void DFS(int v){ if(v==S){ printf("%d ",v); return; }DFS(pre[v]); printf("%d ",v); } int main(){ int i,j,k,l,c; cin>>N>>M>>S>>D; for(i=0;i<M;i++){ cin>>j>>k>>l>>c; v[k].push_back(j); v[j].push_back(k); dis[j][k]=dis[k][j]=l; cost[j][k]=cost[k][j]=c; } Dijkstra(S); DFS(D); printf("%d %d",mindis[D],mincost[D]); return 0; }
采用Dijkstra算法求出最短路径后,再通过DFS对第二标尺进行二次判定
#include<iostream> #include<vector> #include<cstdio> using namespace std; const int INF=1000000; int dis[500][500],mindis[500],cost[500][500]; int mincost=INF;//最少花费 bool vis[500]={false}; vector<int> v[500]; vector<int> pre[500]; vector<int> temppath,path;//临时路径,最优路径 int N,M,S,D; void Dijkstra(int S){ fill(mindis,mindis+500,INF); mindis[S]=0; for(int i=0;i<N;i++){ int u=-1,MIN=INF; for(int j=0;j<N;j++){ if(vis[j]==false&&mindis[j]<MIN){ MIN=mindis[j]; u=j; } } if(u==-1)return; vis[u]=true; for(int i=0;i<v[u].size();i++){ int j=v[u][i]; if(vis[j]==false){ if(mindis[u]+dis[u][j]<mindis[j]){ mindis[j]=mindis[u]+dis[u][j]; pre[j].clear(); pre[j].push_back(u); } else if(mindis[u]+dis[u][j]==mindis[j]){ pre[j].push_back(u); } } } } } void DFS(int v){ temppath.push_back(v); if(v==S){ int tempcost=0; for(int i=temppath.size()-1;i>0;i--){ int id=temppath[i],idNext=temppath[i-1]; tempcost+=cost[id][idNext]; } if(tempcost<mincost){ mincost=tempcost; path=temppath; } temppath.pop_back(); return; } for(int i=0;i<pre[v].size();i++){ DFS(pre[v][i]); } temppath.pop_back(); } int main(){ int i,j,k,l,c; cin>>N>>M>>S>>D; for(i=0;i<M;i++){ cin>>j>>k>>l>>c; v[k].push_back(j); v[j].push_back(k); dis[j][k]=dis[k][j]=l; cost[j][k]=cost[k][j]=c; } Dijkstra(S); DFS(D); for(int i=path.size()-1;i>=0;i--){ printf("%d ",path[i]); } printf("%d %d",mindis[D],mincost); return 0; }
或者从题目出发,直接采用DFS进行递归求解
#include<iostream> #include<vector> #include<cstdio> using namespace std; const int INF=1000000; int dis[500][500],mindis[500],cost[500][500],mincost[500]; int mincosttoD=INF;//到达D的最少路径 int mindistoD=INF;//到达D的最短路径 int N,M,S,D; vector<int>v[500]; vector<int> temppath,path;//临时路径,最优路径 void DFS(int curcity,int curlen,int curcost){ if(curlen>mindis[curcity]) return; temppath.push_back(curcity); if(curcity==D){ if(curlen<mindis[D]||(curlen==mindis[D]&&curcost<mincost[D])){ mindistoD=mindis[D]=curlen; mincosttoD=mincost[D]=curcost; path=temppath; } } else{ if(curlen<mindis[curcity]){//直接对第一标尺进行判断 mindis[curcity]=curlen; } for(int o: v[curcity]){ DFS(o,curlen+dis[o][curcity],curcost+cost[o][curcity]); } } temppath.pop_back(); } int main(){ int i,j,k,l,c; cin>>N>>M>>S>>D; for(i=0;i<M;i++){ cin>>j>>k>>l>>c; v[k].push_back(j); v[j].push_back(k); dis[j][k]=dis[k][j]=l; cost[j][k]=cost[k][j]=c; } fill(mindis,mindis+500,INF); fill(mincost,mincost+500,INF); DFS(S,0,0); for(int i=0;i<path.size();i++){ printf("%d ",path[i]); } cout<<mindistoD<<" "<<mincosttoD; }