>Description
一个 n 个点 m 条边的无重边无自环的无向图,点有点权,边有边权,定义一条路径的权值为路径经过的点权的最大值乘边权最大值。求任意两点间的权值最小的路径的权值。
>Input
第一行两个整数 n,m,分别表示无向图的点数和边数。
第二行 n 个正整数,第 i 个正整数表示点 i 的点权。
接下来 m 行每行三个正整数 ui,vi,wi,分别描述一条边的两个端点和边权。
>Output
n 行每行 n 个整数,第 i 行第 j 个整数表示从 i 到 j 的路径的最小权值,如果从 i 不能到达 j,则该值为 −1。特别地,当 i=j 时输出 0。
>Sample Input
3 3
2 3 3
1 2 2
2 3 3
1 3 1
>Sample Output
0 6 3
6 0 6
3 6 0
对于 20% 的数据,n≤5,m≤8。
对于 50% 的数据,n≤50。
对于 100% 的数据,n≤500,m≤n(n−1)/2,边权和点权不超过 10^9。
>解题思路
看到这个输出和数据范围,我们很容易想到floyed,但重要的是floyed怎么打 比赛时打的floyed爆0了
floyed一般处理的是边权,但是这道题处理的又有点权又有边权又求的是最大值就很难处理
边权我们可以常规处理,这样我们只要考虑点权
我们对点权进行从小到大排序,floyed的中转点从小到大枚举,这样对于(i,j)中的最大点权,就转化成了 m a x ( a i , a t , a j ) max(ai,at,aj) max(ai,at,aj)这三个点了(如果你质疑ai~at之间有更大的点,那这是8可能的,因为这样我们需要在之前用那个点作为中转点求出(i,t),但是我们的中转点从小到大枚举,这样的情况不可能)。
最后加上疯狂卡常
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 505
#define ll long long
#define rg register
using namespace std;
struct point
{
ll c;
int h;
} s[N];
int n, m;
ll a[N], w[N][N], f[N][N];
b