PTA:L3-007 天梯地图
题解:
一开始题目没有看仔细,way = 1,代表单向,way = 0代表双向,不是没有路(很坑)。
两次Dijkstra,然后保存路径。
代码:
#include <bits/stdc++.h>
#define st first
#define sd second
using namespace std;
typedef pair<int,int>pii;
int const N = 500 + 10;
int const inf = 0x7f7f7f7f;
int n,m,s,t;
int dis[N],tim[N],num[N],path1[N],path2[N],a[N],b[N]; //记录路径的上一个点
struct Edge
{
int v,time,len;
Edge(int a,int b,int c):v(a),time(b),len(c){};
};
vector<Edge>G[N];
void Dijkstra1(int s,int t){ //求最快路线,相同找最短路线
priority_queue<pii,vector<pii>,greater<pii> >q;
for(int i=0;i<=n;i++) tim[i] = dis[i] = inf;
q.push(pii(0,s));
tim[s] = dis[s] = 0; path1[s] = -1;
while(!q.empty()){
pii p = q.top(); q.pop();
int x = p.sd;
if(tim[x] < p.st) continue;
for(int i=0;i<G[x].size();i++){
Edge e = G[x][i];
if(tim[e.v] > tim[x] + e.time){
tim[e.v] = tim[x] + e.time;
dis[e.v] = dis[x] + e.len;
path1[e.v] = x;
q.push(pii(tim[e.v],e.v));
}else if(tim[e.v] == tim[x] + e.time){
if(dis[e.v] > dis[x] + e.len){
dis[e.v] = dis[x] + e.len;
path1[e.v] = x;
}
}
}
}
}
void Dijkstra2(int s,int t){ //求最快路线,相同找最短路线
priority_queue<pii,vector<pii>,greater<pii> >q;
for(int i=0;i<=n;i++) dis[i] = num[i] = inf;
q.push(pii(0,s));
dis[s] = 0, num[s] = 0; path2[s] = -1;
while(!q.empty()){
pii p = q.top(); q.pop();
int x = p.sd;
if(dis[x] < p.st) continue;
for(int i=0;i<G[x].size();i++){
Edge e = G[x][i];
if(dis[e.v] > dis[x] + e.len){
dis[e.v] = dis[x] + e.len;
num[e.v] = num[x] + 1;
path2[e.v] = x;
q.push(pii(dis[e.v],e.v));
}else if(dis[e.v] == dis[x] + e.len){
if(num[e.v] > num[x] + 1){
num[e.v] = num[x] + 1;
path2[e.v] = x;
}
}
}
}
}
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
int v1,v2,way,len,time;
scanf("%d%d%d%d%d",&v1,&v2,&way,&len,&time);
G[v1].push_back(Edge(v2,time,len));
if(!way) G[v2].push_back(Edge(v1,time,len));
}
scanf("%d%d",&s,&t);
Dijkstra1(s,t);
Dijkstra2(s,t);
int cnt1 = 0, cnt2 = 0, flag = false;
for(int i=t;i!=-1;i=path1[i]) a[cnt1++] = i;
for(int i=t;i!=-1;i=path2[i]) b[cnt2++] = i;
if(cnt1 == cnt2){
for(int i=0;i<cnt1;i++) if(a[i] != b[i]){
flag = true; //路线不相同
break;
}
}else flag = true;
if(flag){
printf("Time = %d: %d",tim[t],s);
for(int i=cnt1-2;i>=0;i--) printf(" => %d",a[i]); printf("\n");
printf("Distance = %d: %d",dis[t],s);
for(int i=cnt2-2;i>=0;i--) printf(" => %d",b[i]); printf("\n");
}else{
printf("Time = %d; Distance = %d: %d",tim[t],dis[t],s);
for(int i=cnt1-2;i>=0;i--) printf(" => %d",a[i]); printf("\n");
}
return 0;
}