7-2 天梯地圖 (30 分)


7-2 天梯地圖 (30 分)

本題要求你實現一個天梯賽專屬在線地圖,隊員輸入自己學校所在地和賽場地點后,該地圖應該推薦兩條路線:一條是最快到達路線;一條是最短距離的路線。題目保證對任意的查詢請求,地圖上都至少存在一條可達路線。

輸入格式:

輸入在第一行給出兩個正整數N(2 ≤ N ≤ 500)和M,分別為地圖中所有標記地點的個數和連接地點的道路條數。隨后M行,每行按如下格式給出一條道路的信息:

V1 V2 one-way length time 

其中V1V2是道路的兩個端點的編號(從0到N-1);如果該道路是從V1V2的單行線,則one-way為1,否則為0;length是道路的長度;time是通過該路所需要的時間。最后給出一對起點和終點的編號。

輸出格式:

首先按下列格式輸出最快到達的時間T和用節點編號表示的路線:

Time = T: 起點 => 節點1 => ... => 終點 

然后在下一行按下列格式輸出最短距離D和用節點編號表示的路線:

Distance = D: 起點 => 節點1 => ... => 終點 

如果最快到達路線不唯一,則輸出幾條最快路線中最短的那條,題目保證這條路線是唯一的。而如果最短距離的路線不唯一,則輸出途徑節點數最少的那條,題目保證這條路線是唯一的。

如果這兩條路線是完全一樣的,則按下列格式輸出:

Time = T; Distance = 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:

Time = 6: 5 => 4 => 8 => 3 Distance = 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:

Time = 3; Distance = 4: 3 => 2 => 5
#include<stdio.h>
#include<iostream>
using namespace std;
int sum[521];//記錄找最短時間時到原點的距離
struct
{
    int length;
    int time;
}Graph[521][521];//建立地圖
struct
{
    int visit;
    int length;
    int pre;
}LVisit[521];//建立距離、訪問表
struct
{
    int visit;
    int time;
    int pre;
}TVisit[521];//建立時間、訪問表
void InitGraph(int N, int M)//創建並初始化地圖
{
    for(int i=0; i<=N; i++)//初始化各點間的距離和時間均為無窮大
    for(int j=0; j<=N; j++){
        sum[j] = 0;
        Graph[i][j].length = 9999999;
        Graph[i][j].time = 9999999;
    }
    int v1, v2, way, length, time;
    for(int i=0; i<M; i++){//讀取輸入創建地圖
        cin>>v1>>v2>>way>>length>>time;
        Graph[v1][v2].length = length;
        Graph[v1][v2].time = time;
        if(way == 0){//非單行線,兩地可互通
            Graph[v2][v1].length = length;
            Graph[v2][v1].time = time;
        }
    }
}
void InitVisit(int N, int S)// 初始化時間、距離、訪問表
{
    for(int i=0; i<=N; i++){
        LVisit[i].visit = 0;//初始化為未訪問
        LVisit[i].length = Graph[S][i].length;//根據地圖初始化到原點距離
        TVisit[i].visit = 0;//初始化為未訪問
        TVisit[i].time = Graph[S][i].time;//根據地圖初始化時間
        if(TVisit[i].time!=9999999){//如果和原點相通設置前驅點為原點,並設置個時間點到原點距離
            LVisit[i].pre = S;
            TVisit[i].pre = S;
            sum[i] = Graph[S][i].length;
        }
    }
    LVisit[S].visit = 1;//設置原點已訪問
    TVisit[S].visit = 1;//設置原點已訪問
}
void DST_L(int N, int S)//斯特拉求最短距離
{
    for(int j=1; j<N; j++){
           int mlpoint = N;//設置N點為最近點,N點已設為無窮遠
           for(int i=0; i<N; i++){
               if(LVisit[i].length<LVisit[mlpoint].length&&!LVisit[i].visit)
                   mlpoint = i;
           }//求出最近點並設置為已訪問
           LVisit[mlpoint].visit = 1;
           for(int i=0; i<N; i++){//更新距離
                if(!LVisit[i].visit){
                    //更新為更短的距離
                    if(LVisit[i].length>LVisit[mlpoint].length+Graph[mlpoint][i].length){
                        LVisit[i].length = LVisit[mlpoint].length+Graph[mlpoint][i].length;
                        LVisit[i].pre = mlpoint;//設置前驅點
                    }
                    //距離相同則節點少為優
                    else if(LVisit[i].length==LVisit[mlpoint].length+Graph[mlpoint][i].length){
                            int l1=0,l2=0;
                            int pre = LVisit[i].pre;
                            while(pre!=S){
                                l1++;
                                pre = LVisit[pre].pre;
                            }
                            pre = mlpoint;
                            while(pre!=S){
                                l2++;
                                pre = LVisit[pre].pre;
                            }
                            if(l1>l2)//節點多則更新
                            LVisit[i].pre = mlpoint;
                    }
                }
           }
    }

}
void DST_T(int N, int S)//斯特拉求最短時間
{
    for(int j=1; j<N; j++){
        int mtpoint = N;//無窮為最短點
        for(int i=0; i<N; i++){
            if(TVisit[i].time<TVisit[mtpoint].time&&!TVisit[i].visit)
                   mtpoint = i;
        }//求出最短點並設置為已訪問
        TVisit[mtpoint].visit = 1;
        for(int i=0; i<N; i++){
            if(!TVisit[i].visit){
                     //更新最短時間
                    if(TVisit[i].time>TVisit[mtpoint].time+Graph[mtpoint][i].time){
                        TVisit[i].time = TVisit[mtpoint].time+Graph[mtpoint][i].time;
                        TVisit[i].pre = mtpoint;
                        sum[i] = sum[mtpoint] + Graph[mtpoint][i].length;//更新最短時間的距離
                    }//時間相同則根據距離更新,距離短的優先
                    else if(TVisit[i].time==TVisit[mtpoint].time+Graph[mtpoint][i].time){
                        if(sum[i]>sum[mtpoint]+Graph[mtpoint][i].length){//選距離更短的
                            TVisit[i].pre = mtpoint;
                            sum[i] = sum[mtpoint] + Graph[mtpoint][i].length;//更新其距離
                        }
                    }
                }
        }
    }
}
int main()
{
    int N, M;
    cin>>N>>M;
    InitGraph(N,M);//初始化並讀取輸入創建圖
    int S, D;
    cin>>S>>D;
    InitVisit(N, S);//創建並初始化距離、時間、訪問表
    DST_L(N,S);//求最短距離
    DST_T(N,S);//求最短時間
    int lpath[521];//最短距離路徑表
    int tpath[521];//最短時間路徑表
    int l=520, t=520;;
    int pre = D;
    while(pre!=S){//根據目的地不斷往后后移,直到后移到原點
        lpath[l]=pre;
        pre = LVisit[pre].pre;
        l--;
    }
    pre = D;
    while(pre!=S){
        tpath[t] = pre;
        pre = TVisit[pre].pre;
        t--;
    }
    if(t==l){//路徑長度一樣
        int flag = 0;
        for(int i=t+1; i<521; i++){//判斷路徑是否完全相同
            if(tpath[i]!=lpath[i])
            flag = 1;//不相等
        }
        if(flag == 1){//路徑不同
              cout<<"Time = "<<TVisit[D].time<<": "<<S;
              for(int i = t+1; i<521; i++){
                 cout<<" => "<<tpath[i];
              }
              cout<<endl;

              cout<<"Distance = "<<LVisit[D].length<<": "<<S;
              for(int i = l+1; i<521; i++){
                  cout<<" => "<<lpath[i];
              }
         }
         else{//路徑相同
            cout<<"Time = "<<TVisit[D].time<<"; "<<"Distance = "<<LVisit[D].length<<": "<<S;
            for(int i = t+1; i<521; i++){
                 cout<<" => "<<tpath[i];
            }
         }
         return 0;
    }
    //路徑不同
    cout<<"Time = "<<TVisit[D].time<<": "<<S;
    for(int i = t+1; i<521; i++){
        cout<<" => "<<tpath[i];
    }
    cout<<endl;

    cout<<"Distance = "<<LVisit[D].length<<": "<<S;
    for(int i = l+1; i<521; i++){
        cout<<" => "<<lpath[i];
    }

}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM