#include<iostream> #include<vector> #include<climits> #include<string> #include<queue> #include<functional> #include<set> #include<algorithm> usingnamespace std; #define il inline #define min(a,b) (a<b?a:b) #define max(a,b) (a>b?a:b) #define MAX ((int)1e9) #define ALL 201 int n, m; int map[ALL][ALL];//地图 int ft[ALL]; il voidinput() { cin >> n >> m; for (int i = 0; i < n; i++) cin >> ft[i]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (i != j) map[i][j] = MAX;//两个点若不联通,则距离为正无穷 for (int i = 0; i < m; i++)//输入建图 { int x, y, z; cin >> x >> y >> z; map[x][y] = map[y][x] = z; } } int ans[ALL][ALL][ALL];//答案数组 il voidfloyd() { for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { map[i][j] = min(map[i][j], map[i][k] + map[k][j]); } for (int i = 0; i < n; i++)//储存每一层答案 for (int j = 0; j < n; j++) ans[k][i][j] = map[i][j]; } } il intfind(int t) { for (int i = 0; i < n; i++) if (ft[i] > t) return i - 1; return n - 1; } il voidquery() { int t; cin >> t; while (t--) { int x, y, t; cin >> x >> y >> t; int k = find(t);//寻找这个时间点处于那个村庄修好与相应 //的下一个村庄修好的中间时间点 if (t < ft[x] || t < ft[y])//如果时间早于起点或终点修好的时间就输出-1
{ cout << -1 << endl; continue; } int a = ans[k][x][y];//获取第k个村庄修好时的i与j之间的最短路 if (a == MAX)// 如果未联通就输出-1 cout << -1; else cout << a; cout << endl; } } intmain() { input(); floyd(); query(); return0; }
for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j < n; j++) dis[k][i][j] = min(dis[k-1][i][j], dis[k-1][i][k] + dis[k-1][k][j]);
#include<iostream> #include<vector> #include<climits> #include<string> #include<queue> #include<functional> #include<set> #include<algorithm> usingnamespace std; #define il inline #define min(a,b) (a<b?a:b) #define max(a,b) (a>b?a:b) #define MAX ((int)1e9) int map[251][251];//不带点权的最短路 int dis[251][251]; //带点权的最短路 structPoint{ int id, weight;//编号和点权 }point[251];//点集 int ID[251];//记录排序前的编号 int n, m, k; il voidinput() { cin >> n >> m >> k; for (int i = 1,x; i <= n; i++) { cin >> x; point[i].id = i, point[i].weight = x; } sort(point + 1, point + n + 1, [](const Point&l, const Point&r)->bool {return l.weight < r.weight; });//排序 for (int i = 1; i <= n; i++)//记录 ID[point[i].id] = i; for (int i = 1; i <= n; i++)//初始化 for (int j = 1; j <= n; j++) if (i != j) map[i][j] = dis[i][j] = MAX; for (int i = 1; i <= m; i++)//建图 { int x, y, z; cin >> x >> y >> z; map[ID[x]][ID[y]] = map[ID[y]][ID[x]] = min(z, map[ID[x]][ID[y]]); } } il voidfloyd() { for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if (i != j) { //先跑不带点权的 map[i][j] = min(map[i][j], map[i][k] + map[k][j]); //因为动态规划的无后效性,所以可以放一起跑 //距离就是无权最短加上最大点权 dis[i][j] = min(dis[i][j], map[i][j] + max(max(point[i].weight, point[j].weight), point[k].weight)); } } } il voidoutput() { while (k--) { int x, y; cin >> x >> y; cout << dis[ID[x]][ID[y]] << endl; } } intmain() { input(); floyd(); output(); return0; }