この質問では、ラダー競技専用のオンラインマップを実装する必要があります。プレーヤーが学校の場所と会場の場所を入力した後、マップは2つのルートを推奨する必要があります。1つは最速ルート、もう1つは最短距離ルートです。タイトルは、クエリリクエストに対して、マップ上に少なくとも1つの到達可能なルートがあることを保証します。
入力形式:
最初の行に2つの正の整数N(2≤N≤500)とMを入力します。これらは、マップ上でマークされたすべての場所の数と、その場所を結ぶ道路の数です。M行に続いて、各行は次の形式で道路に関する情報を提供します。
V1 V2片道長さ時間
ここで、V1とV2は道路の2つの終点の番号(0からN-1)です。道路がV1からV2への片道である場合、片道は1です。 、それ以外の場合は0、長さは道路の長さ、時間は道路を通過するのに必要な時間です。最後に、開始番号と終了番号のペアが示されます。
出力形式:
まず、最速到着時間Tとノード番号で表されるルートを次の形式で出力します。
時間= T:始点=>ノード1 =>…=>終点
そして、次の行に次の形式で最短距離Dとノード番号で表されるルートを出力します。
距離= D:始点=>ノード1 =>…=>終点。
最速ルートが一意でない場合は、いくつかの最速ルートの最短ルートを出力します。質問により、このルートが一意であることが保証されます。また、最短距離のルートが一意でない場合は、ノード数が最小のルートが出力され、問題が一意であることが保証されます。
2つのルートがまったく同じである場合は、次の形式で出力します。
時間= T;距離= D:始点=>ノード1 =>…=>終点
入力例
1:10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
5 4 0 2 3
5 9 1 1 4
0 6 0 1 1
7 3 1 1 2
8 3 1 1 2
2 5 0 2 2
2 1 1 1 1
1 5 0 1 3
1 4 0 1 1
9 7 1 1 3
3 1 0 2 5
6 3 1 2 1
5 3
出力例1:
時間= 6:5 => 4 => 8 => 3
距離= 3:5 => 1 => 3
入力例2:
7 9
0 4 1 1 1
1 6 1 3 1
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 3 1
3 2 1 2 1
4 5 0 2 2
6 5 1 2 1
3 5
出力例2:
時間= 3; 距離= 4:3 => 2 => 5
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int cnt,s[600],nt[1000010],e[1000010];
int p1[600],p2[600],visit[600];
int dis1[600],t[600],dis2[600],sum[600];
struct Edge
{
int dis,t;
}x[1000090];
struct node1
{
int id,dis;
friend bool operator <(node1 a,node1 b)
{
return a.dis>b.dis;
}
}pre1,nt1;
struct node2
{
int id,t;
friend bool operator <(node2 a,node2 b)
{
return a.t>b.t;
}
}pre2,nt2;
void dij1(int ss,int ee)
{
pre1.id=ss,pre1.dis=0;
priority_queue<node1>q;
memset(visit,0,sizeof visit);
memset(dis1,0x3f3f3f3f,sizeof dis1);
memset(sum,0x3f33f3f,sizeof sum);
sum[ss]=0,dis1[ss]=0;
q.push(pre1);
while(!q.empty())
{
pre1=q.top();
q.pop();
visit[pre1.id]=1;
if(pre1.id==ee) break;
for(int i=s[pre1.id];~i;i=nt[i])
{
int ee=e[i];
if(visit[ee]) continue;
if(dis1[ee]>dis1[pre1.id]+x[i].dis)
{
dis1[ee]=dis1[pre1.id]+x[i].dis;
sum[ee]=sum[pre1.id]+1;
p1[ee]=pre1.id;
nt1.dis=dis1[ee];
nt1.id=ee;
q.push(nt1);
}
else if(dis1[ee]==dis1[pre1.id]+x[i].dis&&sum[ee]>sum[pre1.id]+1)
{
sum[ee]=sum[pre1.id]+1;
p1[ee]=pre1.id;
}
}
}
}
void dij2(int ss,int ee)
{
pre2.id=ss,pre2.t=0;
priority_queue<node2>q;
memset(visit,0,sizeof visit);
memset(t,0x3f3f3f3f,sizeof t);
memset(dis2,0x3f3f3f3f,sizeof dis2);
t[ss]=0,dis2[ss]=0;
q.push(pre2);
while(!q.empty())
{
pre2=q.top();
q.pop();
visit[pre2.id]=1;
if(pre2.id==ee) break;
for(int i=s[pre2.id];~i;i=nt[i])
{
int ee=e[i];
if(visit[ee]) continue;
if(t[ee]>t[pre2.id]+x[i].t)
{
t[ee]=t[pre2.id]+x[i].t;
dis2[ee]=dis2[pre2.id]+x[i].dis;
p2[ee]=pre2.id;
nt2.t=t[ee];
nt2.id=ee;
q.push(nt2);
}
else if(t[ee]==t[pre2.id]+x[i].t&&dis2[ee]>dis2[pre2.id]+x[i].dis)
{
dis2[ee]=dis2[pre2.id]+x[i].dis;
p2[ee]=pre2.id;
}
}
}
}
int main()
{
int n,m;
cin>>n>>m;
cnt=1;
memset(s,-1,sizeof s);
memset(nt,-1,sizeof nt);
int u,v,k,l,time;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>k>>l>>time;
nt[cnt]=s[u],s[u]=cnt,e[cnt]=v,x[cnt].dis=l,x[cnt++].t=time;
if(k==0) nt[cnt]=s[v],s[v]=cnt,e[cnt]=u,x[cnt].dis=l,x[cnt++].t=time;
}
cin>>u>>v;
dij1(u,v);
dij2(u,v);
//判断路径是否重复
int kk=v,flag=1;
while(p1[kk]!=u)
{
if(p1[kk]!=p2[kk]) {
flag=0;break;}
kk=p1[kk];
}
//输出
if(flag)
{
cout<<"Time = "<<t[v]<<"; Distance = "<<dis1[v]<<": "<<u;
stack<int>ss;
kk=v;
while(kk!=u)
{
ss.push(kk);kk=p1[kk];
}
while(ss.size())
{
cout<<" => "<<ss.top();
ss.pop();
}
}
else
{
cout<<"Time = "<<t[v]<<": "<<u;
stack<int>ss;
kk=v;
while(kk!=u)
{
ss.push(kk);kk=p2[kk];
}
while(ss.size())
{
cout<<" => "<<ss.top();
ss.pop();
}
cout<<endl;
cout<<"Distance = "<<dis1[v]<<": "<<u;
kk=v;
while(kk!=u)
{
ss.push(kk);kk=p1[kk];
}
while(ss.size())
{
cout<<" => "<<ss.top();
ss.pop();
}
}
return 0;
}