最优路线【Floyed】

>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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值