7-2 天梯地圖 (30 分)
本題要求你實現一個天梯賽專屬在線地圖,隊員輸入本身學校所在地和賽場地點後,該地圖應該推薦兩條路線:一條是最快到達路線;一條是最短距離的路線。題目保證對任意的查詢請求,地圖上都至少存在一條可達路線。ios
輸入格式:
輸入在第一行給出兩個正整數N
(2 ≤ N
≤ 500)和M
,分別爲地圖中全部標記地點的個數和鏈接地點的道路條數。隨後M
行,每行按以下格式給出一條道路的信息:spa
V1 V2 one-way length time
其中V1
和V2
是道路的兩個端點的編號(從0到N
-1);若是該道路是從V1
到V2
的單行線,則one-way
爲1,不然爲0;length
是道路的長度;time
是經過該路所須要的時間。最後給出一對起點和終點的編號。code
輸出格式:
首先按下列格式輸出最快到達的時間T
和用節點編號表示的路線:blog
Time = T: 起點 => 節點1 => ... => 終點
而後在下一行按下列格式輸出最短距離D
和用節點編號表示的路線:ci
Distance = D: 起點 => 節點1 => ... => 終點
若是最快到達路線不惟一,則輸出幾條最快路線中最短的那條,題目保證這條路線是惟一的。而若是最短距離的路線不惟一,則輸出途徑節點數最少的那條,題目保證這條路線是惟一的。it
若是這兩條路線是徹底同樣的,則按下列格式輸出:io
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]; } }