之前在最短路模型总结中提到了
Q:除起点与终点外,必须在规定的点上走:
A:将floyd的最外层设为规定的点而不是所有点。
所以这道题直接按照点权从小到大排序然后放在最外层循环, 那么显然当前最外层的点即为路径上点的最大值.
注意因为起点和终点没有按照顺序枚举, 所以整条路上的最大值还有可能是起点或者终点.
#include <vector>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 250 + 5;
inline int read(){
char ch = getchar(); int x = 0;
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return x;
}
int N, M, K;
int g[MAXN][MAXN], C[MAXN];
int f[MAXN][MAXN], dis[MAXN][MAXN];
vector<int> nodes;
bool cmp(int &lhs, int &rhs) {
return C[lhs] < C[rhs];
}
int main(){
cin>>N>>M>>K;
memset(g, 0x3f, sizeof(g));
for(int i = 1; i <= N; i++) C[i] = read();
for(int i = 1; i <= M; i++) {
int u = read(), v = read(), c = read();
if(c < g[u][v]) g[u][v] = g[v][u] = c;
}
for(int i = 1; i <= N; i++) nodes.push_back(i);
sort(nodes.begin(), nodes.end(), cmp);
memset(f, 0x3f, sizeof(f));
for(int i = 1; i <= N; i++) f[i][i] = 0;
for(int i = 1; i <= N; i++) g[i][i] = 0;
for(int k = 0; k < N; k++)
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++) if(i != j) {
int u = nodes[i], v = nodes[j], p = nodes[k];
g[u][v] = min(g[u][v], g[u][p] + g[p][v]);
f[u][v] = min(f[u][v], (g[u][p] + g[p][v]) + max(C[p], max(C[u], C[v])));
}
while(K--) {
int u = read(), v = read();
printf("%d\n", f[u][v]);
}
return 0;
}