先处理出最短路上的边。变成一个DAG,然后在DAG上进行DFS。
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<queue> #include<vector> using namespace std; const int INF=0x7FFFFFFF; const int maxn=550; int n,m,C1,C2,tot,ans1,ans2; int val[maxn]; struct Edge { int u,v,L,cost; }e[600000]; int f[600000]; vector<int>g[maxn]; int dis[2][maxn]; int h[maxn]; int path[maxn],ans[maxn]; int cnt; void init() { tot=0; for(int i=0;i<=500;i++) g[i].clear(); memset(h,0,sizeof h); } void add(int a,int b,int c,int d) { e[tot].u=a,e[tot].v=b,e[tot].L=c,e[tot].cost=d; g[a].push_back(tot); tot++; } void read() { scanf("%d%d%d%d",&n,&m,&C1,&C2); for(int i=1;i<=m;i++) { int u,v,L,cost; scanf("%d%d%d%d",&u,&v,&L,&cost); add(u,v,L,cost); add(v,u,L,cost); } } void SPFA(int f,int st) { for(int i=0;i<=500;i++) dis[f][i]=INF; dis[f][st]=0; int flag[maxn]; memset(flag,0,sizeof flag); queue<int>Q; Q.push(st); flag[st]=1; while(!Q.empty()) { int head= Q.front(); Q.pop(); flag[head]=0; for(int i=0;i<g[head].size();i++) { int id=g[head][i]; if(dis[f][head]+e[id].L<dis[f][e[id].v]) { dis[f][e[id].v]=dis[f][head]+e[id].L; if(flag[e[id].v]==0) { Q.push(e[id].v); flag[e[id].v]=1; } } } } } void dfs(int x,int deep,int sum) { path[deep]=x; if(x==C2) { if(sum<ans2) { ans2=sum; cnt=deep; for(int i=0;i<=deep;i++) ans[i]=path[i]; } return; } for(int i=0;i<g[x].size();i++) { int id=g[x][i]; if(f[id]==0) continue; dfs(e[id].v,deep+1,sum+e[id].cost); } } void work() { int len=dis[0][C2]; ans1=len; ans2=999999999; for(int i=0;i<tot;i++) if(dis[0][e[i].u]+e[i].L+dis[1][e[i].v]==len) f[i]=1; cnt=0; dfs(C1,0,0); for(int i=0;i<=cnt;i++) { printf("%d",ans[i]); if(i<tot) printf(" "); else printf(" "); } printf("%d ",ans1); printf("%d ",ans2); } int main() { init(); read(); SPFA(0,C1); SPFA(1,C2); work(); return 0; }