先处理出最短路上的边。变成一个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=;
int n,m,C1,C2,tot,ans1,ans2;
int val[maxn];
struct Edge
{
int u,v,L,cost;
}e[];
int f[];
vector<int>g[maxn];
int dis[][maxn];
int h[maxn]; int path[maxn],ans[maxn];
int cnt; void init()
{
tot=;
for(int i=;i<=;i++) g[i].clear();
memset(h,,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=;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=;i<=;i++) dis[f][i]=INF;
dis[f][st]=;
int flag[maxn]; memset(flag,,sizeof flag);
queue<int>Q; Q.push(st); flag[st]=;
while(!Q.empty())
{
int head= Q.front(); Q.pop(); flag[head]=;
for(int i=;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]==)
{
Q.push(e[id].v);
flag[e[id].v]=;
}
}
}
}
} void dfs(int x,int deep,int sum)
{
path[deep]=x;
if(x==C2)
{
if(sum<ans2)
{
ans2=sum;
cnt=deep;
for(int i=;i<=deep;i++) ans[i]=path[i];
}
return;
}
for(int i=;i<g[x].size();i++)
{
int id=g[x][i];
if(f[id]==) continue;
dfs(e[id].v,deep+,sum+e[id].cost);
}
} void work()
{
int len=dis[][C2];
ans1=len; ans2=;
for(int i=;i<tot;i++)
if(dis[][e[i].u]+e[i].L+dis[][e[i].v]==len)
f[i]=;
cnt=; dfs(C1,,);
for(int i=;i<=cnt;i++)
{
printf("%d",ans[i]);
if(i<tot) printf(" ");
else printf("\n");
}
printf("%d ",ans1);
printf("%d\n",ans2);
} int main()
{
init();
read();
SPFA(,C1);
SPFA(,C2);
work();
return ;
}