PAT L3-007 天梯地图
https://pintia.cn/problem-sets/994805046380707840/problems/994805051153825792
本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线;一条是最短距离的路线。题目保证对任意的查询请求,地图上都至少存在一条可达路线。
输入格式:
输入在第一行给出两个正整数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
代码:
ACACAC
#include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; int N, M, st, en; int mp[550][550], tim[550][550]; int vis[550], see[550], pre[550], num[550]; int dis[550]; int coos[550], nx[550]; vector<int> v[550]; int ans1, ans2; void dijkstra(int act) { dis[act] = 0; pre[act] = -1; num[act] = 1; int temp = act; for(int i = 0; i < N; i ++) { int minn = inf; for(int j = 0; j < N; j ++) { if(vis[j]) continue; if(dis[j] < minn || (dis[j] == minn && num[j] > num[temp])) { temp = j; minn = dis[j]; } } vis[temp] = 1; for(int k = 0; k < N; k ++) { if(vis[k]) continue; if(dis[k] > dis[temp] + mp[temp][k]) { dis[k] = dis[temp] + mp[temp][k]; num[k] = num[temp] + 1; pre[k] = temp; } else if(dis[k] == dis[temp] + mp[temp][k] && num[k] > num[temp] + 1) { num[k] = num[temp] + 1; pre[k] = temp; } } } ans1 = dis[en]; } void Dijkstra(int act) { coos[act] = 0; nx[act] = -1; int temp = act; for(int i = 0; i < N; i ++) { int minn = inf; for(int j = 0; j < N; j ++) { if(see[j]) continue; if(coos[j] < minn || (coos[j] == minn && dis[j] > dis[temp])) { temp = j; minn = coos[j]; } } see[temp] = 1; for(int k = 0; k < N; k ++) { if(see[k]) continue; if(coos[k] > coos[temp] + tim[temp][k]) { coos[k] = coos[temp] + tim[temp][k]; dis[k] = dis[temp] + mp[temp][k]; nx[k] = temp; } else if(coos[k] == coos[temp] + tim[temp][k] && dis[k] > dis[temp] + mp[temp][k]) { dis[k] = dis[temp] + mp[temp][k]; nx[k] = temp; } } } ans2 = coos[en]; } int main() { memset(vis, 0, sizeof(vis)); memset(see, 0, sizeof(see)); memset(dis, inf, sizeof(dis)); memset(mp, inf, sizeof(mp)); memset(tim, inf, sizeof(tim)); memset(coos, inf, sizeof(coos)); scanf("%d%d", &N, &M); for(int i = 0; i < M; i ++) { int uu, vv, dir, len, t; scanf("%d%d%d%d%d", &uu, &vv, &dir, &len, &t); if(dir == 0) { v[uu].push_back(vv); v[vv].push_back(uu); mp[uu][vv] = mp[vv][uu] = len; tim[uu][vv] = tim[vv][uu] = t; } else { v[uu].push_back(vv); mp[uu][vv] = len; tim[uu][vv] = t; } } scanf("%d%d", &st, &en); string s1 = "", s2 = ""; dijkstra(st); Dijkstra(st); stack<int> s3, s4; bool same = true; int n1 = en, n2 = en; vector<int> v1, v2; while(n1 != -1) { v1.push_back(n1); n1 = pre[n1]; } while(n2 != -1) { v2.push_back(n2); n2 = nx[n2]; } if(v1.size() != v2.size()) same = false; else { int m = v1.size(); for(int i = 0; i < m; i ++) { if(v1[i] != v2[i]) { same = false; break; } } } int mintime = ans2; int minway = ans1; if(!same) { printf("Time = %d: ", mintime); stack<int> s2; int lastt = en; while(lastt != -1) { s2.push(lastt); lastt = nx[lastt]; } printf("%d", s2.top()); s2.pop(); while(!s2.empty()) { printf(" => %d", s2.top()); s2.pop(); } printf("\n"); printf("Distance = %d: ", minway); stack<int> s1; int last = en; while(last != -1) { s1.push(last); last = pre[last]; } printf("%d", s1.top()); s1.pop(); while(!s1.empty()) { printf(" => %d", s1.top()); s1.pop(); } } else { printf("Time = %d; Distance = %d: ", mintime, minway); stack<int> s1; int last = en; while(last != -1) { s1.push(last); last = pre[last]; } printf("%d", s1.top()); s1.pop(); while(!s1.empty()) { printf(" => %d", s1.top()); s1.pop(); } } return 0; }
WA 掉的
#include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; int N, M, st, en; int mp[550][550], tim[550][550]; int vis[550], see[550], pre[550], num[550]; int dis[550]; int coos[550], nx[550]; vector<int> v[550]; void dijkstra(int act) { dis[act] = 0; pre[act] = -1; num[act] = 1; int temp = act; for(int i = 0; i < N; i ++) { int minn = inf; for(int j = 0; j < N; j ++) { if(vis[j]) continue; if(dis[j] < minn || (dis[j] == minn && num[j] > num[temp] + 1)) { temp = j; minn = dis[j]; } } vis[temp] = 1; for(int k = 0; k < N; k ++) { if(vis[k]) continue; if(dis[k] > dis[temp] + mp[temp][k]) { dis[k] = dis[temp] + mp[temp][k]; num[k] = num[temp] + 1; pre[k] = temp; } else if(dis[k] == dis[temp] + mp[temp][k] && num[k] > num[temp] + 1) { num[k] = num[temp] + 1; pre[k] = temp; } } } } void Dijkstra(int act) { coos[act] = 0; nx[act] = -1; int temp = act; for(int i = 0; i < N; i ++) { int minn = inf; for(int j = 0; j < N; j ++) { if(see[j]) continue; if(coos[j] < minn || (coos[j] == minn && dis[j] > dis[temp] + mp[temp][j])) { temp = j; minn = coos[j]; } } see[temp] = 1; for(int k = 0; k < N; k ++) { if(see[k]) continue; if(coos[k] > coos[temp] + tim[temp][k]) { coos[k] = coos[temp] + tim[temp][k]; nx[k] = temp; } else if(coos[k] == coos[temp] + tim[temp][k] && dis[k] > dis[temp] + mp[temp][k]) { nx[k] = temp; } } } } int main() { memset(vis, 0, sizeof(vis)); memset(see, 0, sizeof(see)); memset(dis, inf, sizeof(dis)); memset(mp, inf, sizeof(mp)); memset(tim, inf, sizeof(tim)); memset(coos, inf, sizeof(coos)); scanf("%d%d", &N, &M); for(int i = 0; i < M; i ++) { int uu, vv, dir, len, t; scanf("%d%d%d%d%d", &uu, &vv, &dir, &len, &t); if(dir == 0) { v[uu].push_back(vv); v[vv].push_back(uu); mp[uu][vv] = mp[vv][uu] = len; tim[uu][vv] = tim[vv][uu] = t; } else { v[uu].push_back(vv); mp[uu][vv] = len; tim[uu][vv] = t; } } scanf("%d%d", &st, &en); string s1 = "", s2 = ""; dijkstra(st); Dijkstra(st); stack<int> s3, s4; bool same = false; int n1 = en, n2 = en; vector<int> v1, v2; while(n1 != -1) { v1.push_back(n1); n1 = pre[n1]; } while(n2 != -1) { v2.push_back(n2); n2 = nx[n2]; } if(v1.size() != v2.size()) same = false; else { int m = v1.size(); for(int i = 0; i < m; i ++) { if(v1[i] == v2[i]) { same = true; break; } } } int mintime = coos[en]; int minway = dis[en]; if(!same) { printf("Time = %d: ", mintime); stack<int> s2; int lastt = en; while(lastt != -1) { s2.push(lastt); lastt = nx[lastt]; } printf("%d", s2.top()); s2.pop(); while(!s2.empty()) { printf(" => %d", s2.top()); s2.pop(); } printf("\n"); printf("Distance = %d: ", minway); stack<int> s1; int last = en; while(last != -1) { s1.push(last); last = pre[last]; } printf("%d", s1.top()); s1.pop(); while(!s1.empty()) { printf(" => %d", s1.top()); s1.pop(); } } else { printf("Time = %d; Distance = %d: ", mintime, minway); stack<int> s1; int last = en; while(last != -1) { s1.push(last); last = pre[last]; } printf("%d", s1.top()); s1.pop(); while(!s1.empty()) { printf(" => %d", s1.top()); s1.pop(); } } return 0; }
差两个测试点没过 但是实在是写的头大 如果有旁友知道我错的点请私信我!谢谢!!!!