本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线;一条是最短距离的路线。题目保证对任意的查询请求,地图上都至少存在一条可达路线。
输入格式:
输入在第一行给出两个正整数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 => ... => 终点
输入样例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
这道题目在进行命名上出现了很大的问题,再写较为复杂的题目时,应当尽量用小一点的字符串来表示含义,并且在这道题目的最短路径时,不应该用queue而是应当用priority_queue来表示队列,在这道题中涉及俩个方面,在数据的应用上要重新开辟空间来储存。对于最短时间可以运用queue和priority_queue.
#include<iostream>
#include<vector>
#include<queue>
const int INF=0x3fffff;
using namespace std;
typedef pair<int,int> P;
int n,m,s,t,inf=1e8, dis1,dis2;
string ans1, ans2;
struct node
{
int e,w,t;
node(int ee,int ll,int tt):e(ee),w(ll),t(tt){}
};
vector<node> mp[505];
void dfs(int end,int result[],string& a)
{
if(end==s)
{
a+=to_string(end);
return ;
}
dfs(result[end],result,a);
a+=" => "+to_string(end);
return ;
}
void dijkstra1()
{
int result[505],distence[505],visited[505];
queue<P> ans;
for(int i=0;i<n;i++)result[i]=i;
fill(distence,distence+n+1,inf);
fill(visited,visited+n+1,0);
ans.push(P(0,s));
distence[s]=0;
while(!ans.empty())
{
P p=ans.front();
ans.pop();
int u=p.second;
if(distence[u]<p.first)continue;
for(auto i:mp[u])
{
int e=i.e;
int t=i.t;
if(distence[e]>distence[u]+t)
{
distence[e]=distence[u]+t;
ans.push(P(distence[e],e));
visited[e]+=i.w;
result[e]=u;
}
else if(distence[e]==distence[u]+t&&\
visited[e]>visited[u]+i.w)
{
visited[e]=visited[u]+i.w;
result[e]=u;
}
}
}
dfs(t,result,ans1);
dis1=distence[t];
return ;
}
void dijkstra2()
{
int pre[505],dis[505],f[505];
priority_queue<P,vector<P>,greater<P> > ans;
for(int i=0;i<n;i++)pre[i]=i;
fill(dis,dis+n+1,inf);
fill(f,f+n+1,0);
ans.push(P(0,s));
dis[s]=0;
while(!ans.empty())
{
P p=ans.top();
ans.pop();
int u=p.second;
if(dis[u]<p.first)continue;
for(auto i:mp[u])
{
int e=i.e;
int w=i.w;
if(dis[e]>dis[u]+w)
{
dis[e]=dis[u]+w;
ans.push(P(dis[e],e));
f[e]+=i.w;
pre[e]=u;
}
else if(dis[e]==dis[u]+w&&\
f[e]>f[u]+i.w)
{
f[e]=f[u]+i.w;
pre[e]=u;
}
}
}
dfs(t,pre,ans2);
dis2=dis[t];
return ;
}
int main()
{
cin>>n>>m;
for(int n=0;n<m;n++)
{
int begin,end,chose,length,times;
cin>>begin>>end>>chose>>length>>times;
mp[begin].push_back(node(end,length,times));
if(chose==0)mp[end].push_back(node(begin,length,times));
}
cin>>s>>t;
dijkstra1();
dijkstra2();
if(ans1==ans2)
{
cout<<"Time = "<<dis1<<"; Distance = "<<dis2<<": "<<ans2<<endl;
}
else
{
cout<<"Time = "<<dis1<<": "<<ans1<<endl<<"Distance = "<<dis2<<": "<<ans2<<endl;
}
return 0;
}