题目分析:题目给定一个无向图,要求回答对于给定两点2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_数组之间路径最大点权2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_动态规划_02路径最大边权的最小值

很显然是一个多源路径问题,首先要维护边集数组,由于需要计算一个最大点权,一个最大边权,两个最大不好同时处理,因此将点集数组按照权值进行排序,这样可以保证求到“最大值的最小值”,即遍历到大于当前答案的第一个值立即更新掉。

用一个2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_图论_03数组表示2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_动态规划_04为"最小的路径最大点权乘以路径最大边权",并将其初始化为2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_数组_05间权值2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_动态规划_022021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_动态规划_07之间较大的权值。然后按照2021辽宁省大学生程序设计竞赛(正式赛)阿强的路 Floyd最短路、思维_数组_08的思路不断更新下去求多源最短路即可。

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 510;

struct node{
int ser; ll w;
const bool operator< (const node &a){ return w < a.w; }
}a[N];

ll edge[N][N], dp[N][N], b[N];


signed main(){
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, m; cin >> n >> m;
memset(edge, 0x3f, sizeof(edge));
memset(dp, 0x3f, sizeof(dp));
for(int i = 1; i <= n; i++){
cin >> a[i].w;
a[i].ser = i, b[i] = a[i].w;
}
sort(a + 1, a + 1 + n);
for(int i = 1, u, v, w; i <= m; i++){
cin >> u >> v >> w;
edge[u][v] = edge[v][u] = 1ll * w;
dp[u][v] = dp[v][u] = min(dp[u][v], edge[u][v] * max(b[u], b[v]));
}
for(int i = 1; i <= n; i++) dp[i][i] = edge[i][i] = 0;
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
if (edge[i][j] > max(edge[i][a[k].ser], edge[a[k].ser][j])) {
edge[i][j] = max(edge[i][a[k].ser], edge[a[k].ser][j]);
dp[i][j] = min(dp[i][j], edge[i][j] * max({b[i], b[j], a[k].w}));
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(edge[i][j] > 1e16) cout << -1 << ' ';
else cout << dp[i][j] << ' ';
}
cout << endl;
}
return 0;
}