acwing:1601. 在线地图
输入我们的当前位置和目的地,在线地图就可以推荐一些行进路线。
现在你的工作是向用户推荐两条路线:一条是最短路线,另一条是最快路线。
保证任何询问的两地之间都存在至少一条路线。
输入格式
第一行包含两个整数 N 和 M,表示地图中共有 N个路口(编号 0∼N−1)和 M 个街道。
接下来 M 行,每行描述一条街道,格式如下:
V1 V2 one-way length time
V1
和V2
是两个路口的编号,表示这两个路口之间存在一条街道,one-way
如果为 1 则表示这条街道是单行道,只能从V1
前往V2
。如果为 0 表示是双行道,可随意通行。length
是街道的长度,time
是通过这条街道花费的时间。最后一行,将给出起点和终点路口的编号。
输出格式
第一行输出路程最短的路线,并输出最短路程 D,格式如下:
Distance = D: source -> v1 -> ... -> destination
第二行输出用时最快的路线,并输出最短用时 T,格式如下:
Time = T: source -> w1 -> ... -> destination
如果最短路线不唯一,则输出用时最短的那条路线(保证唯一)。
如果最快路线不唯一,则输出经过路口最少的那条路线(保证唯一)。
如果最短路线和最快路线经过的路口序列完全相同,则以如下格式将两个信息输出在一行:
Distance = D; Time = T: source -> u1 -> ... -> destination
思路:
两次dijkstra,分别对距离,时间用dijkstra,注意第二次是时间和节点数(我下意识以为是时间和距离直接waring了)。
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int d[N][N],f[N][N];
int dis[N],fee[N],Cnt[N];
int path1[N],path2[N];
bool st[N];
int n,m,sa,en;
void dijk1()
{
memset(dis,0x3f,sizeof(dis));
memset(fee,0x3f,sizeof(fee));
dis[sa]=0,fee[sa]=0;
for(int i=0;i<n;i++){
int t=-1;
for(int j=0;j<n;j++){
if(!st[j]&&(t==-1||dis[t]>dis[j])){
t=j;
}
}
st[t]=true;
for(int j=0;j<n;j++){
if(dis[j]>dis[t]+d[t][j]){
dis[j]=d[t][j]+dis[t];
fee[j]=fee[t]+f[t][j];
path1[j]=t;
}else if(dis[j]==dis[t]+d[t][j]){
if(fee[j]>fee[t]+f[t][j]){
fee[j]=fee[t]+f[t][j];
path1[j]=t;
}
}
}
}
}
void dijk2(){
memset(st,false,sizeof(st));
memset(dis,0x3f,sizeof(dis));
memset(fee,0x3f,sizeof(fee));
dis[sa]=0,fee[sa]=0,Cnt[sa]=1;
for(int i=0;i<n;i++){
int t=-1;
for(int j=0;j<n;j++){
if(!st[j]&&(t==-1||fee[t]>fee[j])){
t=j;
}
}
st[t]=true;
for(int j=0;j<n;j++){
if(fee[j]>fee[t]+f[t][j]){
Cnt[j]=Cnt[t]+1;
fee[j]=f[t][j]+fee[t];
dis[j]=dis[t]+d[t][j];
path2[j]=t;
}else if(fee[j]==fee[t]+f[t][j]){
if(Cnt[j]>Cnt[t]+1){
dis[j]=dis[t]+d[t][j];
Cnt[j]=Cnt[t]+1;
path2[j]=t;
}
}
}
}
}
void solve()
{
memset(d,0x3f,sizeof(d));
memset(f,0x3f,sizeof(f));
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c,e,g;
cin>>a>>b>>c>>e>>g;
if(c==0){
d[a][b]=min(d[a][b],e),f[a][b]=min(f[a][b],g);
d[b][a]=min(d[b][a],e),f[b][a]=min(f[b][a],g);
}else{
d[a][b]=min(d[a][b],e);
f[a][b]=min(f[a][b],g);
}
}
cin>>sa>>en;
int ans1,ans2,ans3,ans4;
dijk1();
ans1=dis[en],ans2=fee[en];
dijk2();
ans3=dis[en],ans4=fee[en];
bool flag=0;
for(int i=en;i!=sa;i=path1[i]){
int o=path2[i];
if(path1[i]!=o){
flag=1;
break;
}
}
if(flag){
cout<<"Distance = "<<ans1<<": ";
int Path1[N],cnt1,Path2[N],cnt2;
for(int i=en;i!=sa;i=path1[i]){
Path1[cnt1++]=path1[i];
}
for(int i=en;i!=sa;i=path2[i]){
Path2[cnt2++]=path2[i];
}
for(int i=cnt1-1;i>=0;i--){
cout<<Path1[i]<<" -> ";
}
cout<<en<<endl;
cout<<"Time = "<<ans4<<": ";
for(int i=cnt2-1;i>=0;i--){
cout<<Path2[i]<<" -> ";
}
cout<<en<<endl;
}else{
int Path1[N],cnt1;
for(int i=en;i!=sa;i=path1[i]){
Path1[cnt1++]=path1[i];
}
cout<<"Distance = "<<ans1<<"; ";
cout<<"Time = "<<ans4<<": ";
for(int i=cnt1-1;i>=0;i--){
cout<<Path1[i]<<" -> ";
}
cout<<en<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t=1;
while(t--){
solve();
}
return 0;
}
最后与你共勉,望进步。