本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线;一条是最短距离的路线。题目保证对任意的查询请求,地图上都至少存在一条可达路线。
输入格式:
输入在第一行给出两个正整数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
算法思路:单源最短路径拓展了一下
#include<stdio.h>
#include<stack>
using namespace std;
const int MAX = 1000000;
int mapl[500][500];
int mapt[500][500];
int vis[500];
int pre[500];
int dis[500];
int tim[500];
int n;
void init() {
int i;
for (i = 0; i<n; i++) {
vis[i] = false;
dis[i] = MAX;
tim[i] = MAX;
}
}
void dijkstraForTime(int source, int dest) {
init();
int i;
int u = source;
tim[u] = 0;
dis[u] = 0;
while (u != dest) {
vis[u] = true;
int tempt, templ;
for (i = 0; i<n; i++) {
if (vis[i])continue;
tempt = mapt[u][i] + tim[u];
templ = mapl[u][i] + dis[u];
if (tempt<tim[i]) {
tim[i] = tempt;
dis[i] = templ;
pre[i] = u;
}
else if (tim[i] != MAX&&tempt == tim[i]) {
if (templ<dis[i]) {
dis[i] = templ;
pre[i] = u;
}
}
}
tempt = MAX;
for (i = 0; i<n; i++) {
if (!vis[i] && tempt>tim[i]) {
tempt = tim[i];
u = i;
}
}
}
}
void dijkstraForLength(int source, int dest) {
init();
int i;
int u = source;
tim[u] = 1;
dis[u] = 0;
while (u != dest) {
vis[u] = true;
int tempt, templ;
for (i = 0; i<n; i++) {
if (vis[i])continue;
tempt = 1 + tim[u];
templ = mapl[u][i] + dis[u];
if (templ<dis[i]) {
tim[i] = tempt;
dis[i] = templ;
pre[i] = u;
}
else if (dis[i] != MAX&&templ == dis[i]) {
if (tempt<tim[i]) {
tim[i] = tempt;
pre[i] = u;
}
}
}
templ = MAX;
for (i = 0; i<n; i++) {
if (!vis[i] && templ>dis[i]) {
templ = dis[i];
u = i;
}
}
}
}
void getroad(int source, int dest, stack<int>& citys, int* pre) {
int u = dest;
while (u != source) {
citys.push(u);
u = pre[u];
}
citys.push(source);
}
bool judge(stack<int> a, stack<int> b) {
int len1 = a.size();
int len2 = b.size();
if (len1 != len2) return false;
while (len1--) {
if (a.top() != b.top()) return false;
a.pop();
b.pop();
}
return true;
}
int main() {
int m;
scanf("%d%d", &n, &m);
int i;
for (i = 0; i<n; i++)
for (int j = 0; j<n; j++)
{
mapl[i][j] = MAX;
mapt[i][j] = MAX;
}
int v1, v2, style, length, time;
for (i = 0; i<m; i++) {
scanf("%d%d%d%d%d", &v1, &v2, &style, &length, &time);
mapl[v1][v2] = length;
mapt[v1][v2] = time;
if (!style) {
mapl[v2][v1] = length;
mapt[v2][v1] = time;
}
}
int source, dest, mintime, mindis;
scanf("%d%d", &source, &dest);
dijkstraForTime(source, dest);
mintime = tim[dest];
stack<int> troad;
getroad(source, dest, troad, pre);
dijkstraForLength(source, dest);
mindis = dis[dest];
stack<int> lroad;
getroad(source, dest, lroad, pre);
if (judge(lroad, troad))
{
printf("Time = %d; Distance = %d: %d", mintime, mindis, lroad.top());
lroad.pop();
while (!lroad.empty()) {
printf(" => %d", lroad.top());
lroad.pop();
}
}
else {
printf("Time = %d: %d", mintime, troad.top());
troad.pop();
while (!troad.empty()) {
printf(" => %d", troad.top());
troad.pop();
}
printf("\n");
printf("Distance = %d: %d", mindis, lroad.top());
lroad.pop();
while (!lroad.empty()) {
printf(" => %d", lroad.top());
lroad.pop();
}
}
printf("\n");
return 0;
}