L3-007. 天梯地圖
本題要求你實現一個天梯賽專屬線上地圖,隊員輸入自己學校所在地和賽場地點後,該地圖應該推薦兩條路線:一條是最快到達路線;一條是最短距離的路線。題目保證對任意的查詢請求,地圖上都至少存在一條可達路線。
輸入格式:
輸入在第一行給出兩個正整數N(2 <= N <=500)和M,分別為地圖中所有標記地點的個數和連線地點的道路條數。隨後M行,每行按如下格式給出一條道路的資訊:
V1 V2 one-way length time
其中V1和V2是道路的兩個端點的編號(從0到N-1);如果該道路是從V1到V2的單行線,則one-way為1,否則為0;length是道路的長度;time是通過該路所需要的時間。最後給出一對起點和終點的編號。
輸出格式:
首先按下列格式輸出最快到達的時間T和用節點編號表示的路線:
Time = T: 起點 => 節點1 => ... => 終點
然後在下一行按下列格式輸出最短距離D和用節點編號表示的路線:
Distance = D: 起點 => 節點1 => ... => 終點
如果最快到達路線不唯一,則輸出幾條最快路線中最短的那條,題目保證這條路線是唯一的。而如果最短距離的路線不唯一,則輸出途徑節點數最少的那條,題目保證這條路線是唯一的。
如果這兩條路線是完全一樣的,則按下列格式輸出:
Time = T; Distance = D: 起點 => 節點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
Time = 3; Distance = 4: 3 => 2 => 5
#include "iostream"
#include "stack"
#include "vector"
#include "stdio.h"
using namespace std;
#define Sky 1<<29
#define Max 510
int Top,Edge,Start,End;
int Map_T[Max][Max],Map_W[Max][Max];
int Way_T[Max],Way_W[Max];
int Dist_W[Max],Dist_T[Max];
bool Move_W[Max],Move_T[Max];
int Sum_W[Max],Sum_T[Max];
void Display()
{
vector<int>Walk1,Walk2;
stack<int>way1,way2;
int x;
x=Way_W[End];
Walk1.push_back(Start);
while(x!=Start)
{
way1.push(x);
x=Way_W[x];
}
while(!way1.empty())
{
Walk1.push_back(way1.top());
way1.pop();
}
Walk1.push_back(End);
Walk2.push_back(Start);
x=Way_T[End];
while(x!=Start)
{
way2.push(x);
x=Way_T[x] ;
}
while(!way2.empty())
{
Walk2.push_back( way2.top() );
way2.pop();
}
Walk2.push_back(End);
if(Walk2.size()!=Walk1.size())
{
cout<<"Time = "<<Dist_T[End]<<": "<<Walk2[0];
for(int i=1;i<Walk2.size();i++)
{
cout<<" => "<<Walk2[i];
}
cout<<endl;
cout<<"Distance = "<<Dist_W[End]<<": "<<Walk1[0];
for(int i=1;i<Walk1.size();i++)
{
cout<<" => "<<Walk1[i];
}
}
else
{ int i;
for(i=0;i<Walk2.size();i++)
{
if(Walk1[i]!=Walk2[i])break;
}
if(i==Walk2.size())
{
cout<<"Time = "<<Dist_T[End]<<"; ";
cout<<"Distance = "<<Dist_W[End]<<": "<<Walk2[0];
for(i=1;i<Walk2.size();i++)
{
cout<<" => "<<Walk2[i];
}
}
else
{
cout<<"Time = "<<Dist_T[End]<<": "<<Walk2[0];
for(int i=1;i<Walk2.size();i++)
{
cout<<" => "<<Walk2[i];
}
cout<<endl;
cout<<"Distance = "<<Dist_W[End]<<": "<<Walk1[0];
for(int i=1;i<Walk1.size();i++)
{
cout<<" => "<<Walk1[i];
}
}
}
}
void DijLen()
{
int i,j;
for(i=0;i<Top;i++)
{
Move_W[i]=false;
Dist_W[i]=Map_W[Start][i];
Way_W[i]=Start;
if(Dist_W[i]!=Sky)
{
Sum_W[i]=2;
}
else
{
Sum_W[i]=1;
}
}
Move_W[Start]=false;
Dist_W[Start]=0;
for(i=0;i<Top;i++)
{
int k_w=-1,Min_w=Sky;
for(j=0;j<Top;j++)
{
if(Dist_W[j]<Min_w && !Move_W[j])
{
k_w=j;
Min_w=Dist_W[j];
}
}
if(k_w==-1 || k_w==End)
break;
Move_W[k_w]=true;
for(j=0;j<Top;j++)
{
if(Dist_W[j]==Dist_W[k_w]+Map_W[k_w][j] &&!Move_W[j] )
{
if(Sum_W[j]>Sum_W[k_w]+1)
{
Way_W[j]=k_w;
}
}
if(Dist_W[j]>Dist_W[k_w]+Map_W[k_w][j] &&!Move_W[j] )
{
Dist_W[j]=Dist_W[k_w]+Map_W[k_w][j];
Sum_W[j]=Sum_W[k_w]+1;
Way_W[j]=k_w;
}
}
}
}
void DijT()
{
int i,j,Dist[Max];
for(i=0;i<Top;i++)
{
Dist_T[i]=Map_T[Start][i];
Move_T[i]=false;
Way_T[i]=Start;
Dist[i]=Dist_W[i];
}
Move_T[Start]=true;
Dist_T[i]=0;
for(i=0;i<Top;i++)
{
int k=-1,Min=Sky;
for(j=0;j<Top;j++)
{
if(!Move_T[j]&& Min>Dist_T[j])
{
k=j;
Min=Dist_T[j];
}
}
if(k==-1 || k==End) break;
Move_T[k]=true;
for(j=0;j<Top;j++)
{
if( Dist_T[j]==Dist_T[k]+Map_T[k][j] &&!Move_T[j] )
{
if( Dist[j]>Dist[k]+Map_W[k][j])
{
Way_T[j]=k;
Dist[j]=Dist[j]+Map_W[k][j];
}
}
if(Dist_T[j]>Dist_T[k]+Map_T[k][j] &&!Move_T[j] )
{
Dist_T[j]=Dist_T[k]+Map_T[k][j];
Way_T[j]=k;
Dist[j]=Dist[j]+Map_W[k][j];
}
}
}
}
int main()
{
//freopen("1.txt","r",stdin);
cin>>Top>>Edge;
int i,j;
for(i=0;i<Top;i++)
{
for(j=0;j<Top;j++)
{
Map_T[i][j]=Map_W[j][i]=Sky;
}
}
for(i=0;i<Edge;i++)
{
int x,y,z,a,b;
cin>>x>>y>>z>>a>>b;
Map_T[x][y]=b;
Map_W[x][y]=a;
if(z==0)
{
Map_T[y][x]=b;
Map_W[y][x]=a;
}
}
cin>>Start>>End;
DijLen();
DijT();
Display();
return 0;
}