1.Dijkstra + DFS
2.先把所有路径储出来再dfs路径找符合条件的解
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int grape[505][505],wt[505][505];
bool vis[505];
int dis[505],tim[505];
vector<vector<int > > pa1,pa2;
vector<int > tp1,tp2,ans1,ans2;
int n,m;
int fir,ed;
int minl=inf,mint=inf,mincnt=inf;
void dfs(int x){
tp1.push_back(x);
if(x == fir){
int l=0,t=0;
int pre = tp1[tp1.size()-1];
for(int i = tp1.size()-2;i>=0;i--){
l +=grape[pre][tp1[i]];
t +=wt[pre][tp1[i]];
pre = tp1[i];
}
if(l<minl){
//更新条件的时候一定要小心!!!
minl = l;
mint = t; //一开始忘记更新这个调半天。。。。
ans1.clear();
ans1 = tp1;
}else if(l==minl&&t<mint){
mint = t;
ans1.clear();
ans1 = tp1;
}
tp1.pop_back();
return;
}
for(int i=0;i<pa1[x].size();i++){
dfs(pa1[x][i]);
}
tp1.pop_back();
return;
}
void dfs1(int x){
// cout<<x<<"\n";
tp2.push_back(x);
if(x == fir){
int t=0;
int pre = tp2[tp2.size()-1];
for(int i = tp2.size()-2;i>=0;i--){
t +=wt[pre][tp2[i]];
pre = tp2[i];
}
if(t<mint){
mincnt = tp2.size();
mint = t;
ans2.clear();
ans2 = tp2;
}else if(t==mint&&mincnt > tp2.size()){
mincnt = tp2.size();
ans2.clear();
ans2 = tp2;
}
tp2.pop_back();
return;
}
// cout<<pa2[5].size()<<" dasda\n";
for(int i=0;i<pa2[x].size();i++){
dfs1(pa2[x][i]);
}
tp2.pop_back();
return;
}
int main()
{
fill(grape[0],grape[0]+505*505,inf);
fill(wt[0],wt[0]+505*505,inf);
fill(dis,dis+505,inf);
fill(tim,tim+505,inf);
scanf("%d%d",&n,&m);
pa1.resize(n);
pa2.resize(n);
for(int i=0;i<m;i++){
int v1,v2,one_way,len,t;
scanf("%d%d%d%d%d",&v1,&v2,&one_way,&len,&t);
if(one_way==1){
grape[v1][v2] = len;
wt[v1][v2] = t;
}
else{
grape[v1][v2] = len;
wt[v1][v2] = t;
grape[v2][v1] = len;
wt[v2][v1] = t;
}
}
scanf("%d%d",&fir,&ed);
//设初始条件
dis[fir] = 0;
tim[fir] = 0;
for(int i=0;i<n;i++){
int u = -1,minn = inf;
for(int j=0;j<n;j++){
if(vis[j]==false&&dis[j]<minn){
minn = dis[j];
u = j;
}
}
if(u==-1) break;
vis[u] = true;
for(int v = 0;v < n;v++){
if(vis[v]==false&&grape[u][v] != inf){
if(dis[v] > dis[u] + grape[u][v]){
dis[v] = dis[u] + grape[u][v];
pa1[v].clear();
pa1[v].push_back(u);
}
else if(dis[v] == dis[u] + grape[u][v]){
pa1[v].push_back(u);
}
}
}
}
fill(vis,vis+505,false);
for(int i=0;i<n;i++){
int u = -1,minn = inf;
for(int j=0;j<n;j++){
if(vis[j]==false&&tim[j]<minn){
minn = tim[j];
u = j;
}
}
if(u==-1) break;
vis[u] = true;
for(int v = 0;v < n;v++){
if(vis[v]==false&&wt[u][v] != inf){
if(tim[v] > tim[u] + wt[u][v]){
tim[v] = tim[u] + wt[u][v];
pa2[v].clear();
pa2[v].push_back(u);
}
else if(tim[v] == tim[u] + wt[u][v]){
pa2[v].push_back(u);
}
}
}
}
//dfs两次分别找最短路和最快路
dfs(ed);
mint = inf;
dfs1(ed);
if(ans1.size()!=ans2.size()){
printf("Distance = %d:",dis[ed]);
printf(" %d",ans1[ans1.size()-1]);
for(int i=ans1.size()-2;i>=0;i--)
printf(" -> %d",ans1[i]);
}
else{
bool f = false;
for(int i=0;i<ans1.size();i++){
if(ans1[i]!=ans2[i]){
printf("Distance = %d:",dis[ed]);
printf(" %d",ans1[ans1.size()-1]);
for(int i=ans1.size()-2;i>=0;i--)
printf(" -> %d",ans1[i]);
f = true;
break;
}
}
if(f==false){
printf("Distance = %d; Time = %d: %d",dis[ed],tim[ed],ans1[ans1.size()-1]);
for(int i=ans1.size()-2;i>=0;i--)
printf(" -> %d",ans1[i]);
return 0;
}
}
printf("\n");
printf("Time = %d: %d",tim[ed],ans2[ans2.size()-1]);
for(int i = ans2.size()-2;i>=0;i--)
printf(" -> %d",ans2[i]);
return 0;
}