L3-007ラダーマップ(30点):最短経路

この質問では、ラダー競技専用のオンラインマップを実装する必要があります。プレーヤーが学校の場所と会場の場所を入力した後、マップは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;
}

おすすめ

転載: blog.csdn.net/weixin_43540515/article/details/110258369