思路:
2遍Dijkstra,要记录主要信息和次要信息,还有前驱结点,递归寻找路径即可,在此是用了邻接矩阵存图,较为方便
代码:
#include<bits/stdc++.h>
#define f(i,a,b) for(int i=a;i<b;i++)
#define ff(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
#define debug(x) cout<<#x<<" : "<<x<<endl;
#define IN freopen("E:\\信竞\\信竞文件夹\\in_c.TXT","r",stdin);
using namespace std;
const int N=505;
int n,m,st,ed;
//g1是距离,g2是时间
int g1[N][N],g2[N][N];
int t_1[N],d_1[N],d_2[N],num_2[N];
int st_1[N],st_2[N],pr[2][N];
vector<int> v[2];
void pri(int x,int flag){
if(x!=st)pri(pr[flag][x],flag);
if(x!=ed)v[flag].push_back(x);
}
//时间
void dij_t(){
memset(t_1,0x3f,sizeof t_1);
t_1[st]=0;
f(j,0,n){
int t=-1;;
f(i,0,n)
if(!st_1[i] && (t==-1||t_1[t]>t_1[i]))t=i;
st_1[t]=1;
f(i,0,n){
if(t_1[i]==t_1[t]+g2[t][i] ? d_1[i]>d_1[t]+g1[t][i] : t_1[i]>t_1[t]+g2[t][i]){
t_1[i]=t_1[t]+g2[t][i],d_1[i]=d_1[t]+g1[t][i],pr[0][i]=t;
}
}
}
pri(ed,0);
}
//距离
void dij_d(){
memset(d_2,0x3f,sizeof d_2);
d_2[st]=0;
f(j,0,n){
int t=-1;;
f(i,0,n)
if(!st_2[i] && (t==-1||d_2[t]>d_2[i]))t=i;
st_2[t]=1;
f(i,0,n){
if(d_2[i]==d_2[t]+g1[t][i] ? num_2[i]>num_2[t]+1 : d_2[i]>d_2[t]+g1[t][i]){
d_2[i]=d_2[t]+g1[t][i],num_2[i]=num_2[t]+1,pr[1][i]=t;
}
}
}
pri(ed,1);
}
int main(){
//IN
cin>>n>>m;
memset(g1,0x3f,sizeof g1);
memset(g2,0x3f,sizeof g2);
f(i,0,m){
int a,b,c,l,t;
cin>>a>>b>>c>>l>>t;
if(!c){
g1[a][b]=g1[b][a]=min(g1[a][b],l);
g2[a][b]=g2[b][a]=min(g2[a][b],t);
}
else{
g1[a][b]=min(g1[a][b],l);
g2[a][b]=min(g2[a][b],t);
}
}
cin>>st>>ed;
dij_t(),dij_d();
if(v[0]==v[1])printf("Time = %d; ",t_1[ed]);
else{
printf("Time = %d: ",t_1[ed]);
for(auto i:v[0]){
cout<<i<<" => ";
}
cout<<ed<<endl;
}
printf("Distance = %d: ",d_2[ed]);
for(auto i:v[1]){
cout<<i<<" => ";
}
cout<<ed<<endl;
}