考查点:最短路径,Dijkstra算法,DFS
思路和提交情况:本题直接DJ算法即可,第一次提交Dj没写对,主要是第一个循环找最小值时忘记判断vis,第二次没考虑相同路径,最费时间的是逻辑搞错了,题目中虽然要输出最短路中最快的但是在维护时间这个权值时不是用通过最快路径得到权值,而是在最短路径中同时更新的自己的权值,还有因为权值都是同一个数组所以调用两个dj方法顺序要按题目来。
#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define FOR(i, x, y) for(int i = x; i <= y; i++)
#define rFOR(i, x, y) for(int i = x; i >= y; i--)
#define MAXN 600
#define oo 0x3f3f3f3f
using namespace std;
int n,m;
int G[MAXN][MAXN];
int cost[MAXN][MAXN];
int num[MAXN];
int pre[MAXN];
int d[MAXN];
int w[MAXN];
int vis[MAXN];
int pret[MAXN];
void DJ_TIME(int s)
{
memset(vis,0,sizeof(vis));
fill(w,w+MAXN,oo);
w[s]=0;
num[s]=1;
memset(pre,-1,sizeof(pre));
FOR(i,0,n-1)
{
int MIN=oo;
int u=-1;
FOR(j,0,n-1)
{
if(w[j]<MIN&&vis[j]==0){
MIN=w[j];
u=j;
}
}
if(u==-1)return;
vis[u]=1;
FOR(j,0,n-1)
{
if(cost[u][j]!=oo&&vis[j]==0)
{
if(w[j]>w[u]+cost[u][j]){
w[j]=w[u]+cost[u][j];
pre[j]=u;
num[j]=num[u]+1;
}else if(w[j]==w[u]+cost[u][j]){
if(num[j]>num[u]+1){
pre[j]=u;
num[j]=num[u]+1;
}
}
}
}
}
}
void DJ(int s)
{
memset(vis,0,sizeof(vis));
fill(d,d+MAXN,oo);
fill(w,w+MAXN,oo);
d[s]=0;
w[s]=0;
memset(pret,-1,sizeof(pret));
FOR(i,0,n-1)
{
int MIN=oo;
int u=-1;
FOR(j,0,n-1)
{
if(d[j]<MIN&&vis[j]==0){
MIN=d[j];
u=j;
}
}
if(u==-1)return;
vis[u]=1;
FOR(j,0,n-1)
{
if(G[u][j]!=oo&&vis[j]==0)
{
if(d[j]>d[u]+G[u][j]){
d[j]=d[u]+G[u][j];
w[j]=w[u]+cost[u][j];
pret[j]=u;
}else if(d[j]==d[u]+G[u][j]){
if(w[j]>w[u]+cost[u][j]){
w[j]=w[u]+cost[u][j];
pret[j]=u;
}
}
}
}
}
}
void DFS(int s,int d)
{
if(s==d){
printf("%d",s);
return;
}else{
DFS(s,pre[d]);
printf(" -> %d",d);
}
}
void DFST(int s,int d)
{
if(s==d){
printf("%d",s);return;
}else{
DFST(s,pret[d]);
printf(" -> %d",d);
}
}
int main()
{
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif // LOCAL
scanf("%d%d",&n,&m);
fill(G[0],G[0]+MAXN*MAXN,oo);
fill(cost[0],cost[0]+MAXN*MAXN,oo);
FOR(i,0,m-1)
{
int u,v;
int way,len,time;
scanf("%d%d%d%d%d",&u,&v,&way,&len,&time);
if(way==0){
G[u][v]=G[v][u]=len;
cost[u][v]=cost[v][u]=time;
}else{
G[u][v]=len;cost[u][v]=time;
}
}
int st,dn;
scanf("%d%d",&st,&dn);
DJ(st);
DJ_TIME(st);
int flag=0;
int k=dn;
while(pre[k]==pret[k]&&k!=st){
k=pre[k];
}
if(k==st){
printf("Distance = %d; Time = %d: ",d[dn],w[dn]);
DFS(st,dn);
return 0;
}
printf("Distance = %d: ",d[dn]);
DFST(st,dn);
printf("\n");
printf("Time = %d: ",w[dn]);
DFS(st,dn);
return 0;
}