您的位置:首页 > 编程语言 > C语言/C++

PTA 一 天梯地图

2017-03-19 21:44 555 查看
本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线;一条是最短距离的路线。题目保证对任意的查询请求,地图上都至少存在一条可达路线。


输入格式:

输入在第一行给出两个正整数
N
(2 \le≤ 
N
 \le≤ 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 C++