【Floyd】【2020.8.23NOIP模拟赛】最优路线

L i n k Link Link

l u o g u   T 145192 luogu\ T145192 luogu T145192

D e s c r i p t i o n Description Description

在这里插入图片描述

S a m p l e Sample Sample I n p u t Input Input

3 3 
2 3 3 
1 2 2 
2 3 3 
1 3 1 

S a m p l e Sample Sample O u t p u t Output Output

0 6 3 
6 0 6 
3 6 0

H i n t Hint Hint

对于 20%的数据,n<=5,m<=8。
对于 50%的数据,n<=50
对于 100%的数据,n<=500,m<=n*(n-1)/2,
				边权和点权不超过 10^9。

S o l u t i o n Solution Solution

按点权排序然后跑 f l o y e d floyed floyed,中转点和枚举的 i , j i,j i,j一定是最大的三个点,然后判断一下是否要更新就好了
加快读快输,开long long

C o d e Code Code

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long

using namespace std;

int n, m;
int a[505];
ll w[505][505], f[505][505];


struct awsl
{ 
	ll x;
	int num;
}s[124755];

ll maxx(ll a, ll b)
{
	if (a > b) return a;
	else return b;
}

ll minx(ll a, ll b)
{
	if (a > b) return b;
	else return a;
}

bool cmp(awsl a, awsl b)
{return a.x < b.x;} 

int read() 
{
	ll x = 0, flag = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') flag = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
	return x * flag;
}

void write(ll x)
{
    if (x < 0) { 
		x = -x; 
		putchar('-');
	}
	if (x > 9) write(x / 10);
	putchar(x % 10 + 48);
	return;
}

int main()
{
	memset(w, 0x7f, sizeof(w));
	memset(f, 0x7f, sizeof(f));
	n = read(); m = read();
	for (int i = 1; i <= n; ++i) { 
		a[i] = read();
		s[i].x = a[i]; s[i].num = i;
	} 
	for (int i = 1; i <= m; ++i)
	{
		ll u, v, l;
		u = read(); v = read(); l = read();
		w[v][u] = w[u][v] = l;
		f[u][v] = f[v][u] = (ll) l * maxx(a[u], a[v]);
	}
	sort(s + 1, s + n + 1, cmp);
	for (int i = 1; i <= n; ++i)
	{
		int t = s[i].num;
		for (int j = 1; j <= n; ++j)
		for (int k = 1; k <= n; ++k)
			if (j != t && k != t && k != j)
			if (w[j][k] > maxx(w[j][t], w[k][t]))
			{
				w[j][k] = maxx(w[j][t], w[t][k]);
				f[j][k] = minx(f[j][k], w[j][k] * maxx(a[t], maxx(a[k], a[j])));
			}
	}
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= n; ++j)
		{
			if (i == j) putchar('0');
			else if (f[i][j] == f[0][0]) printf("-1");
			else write(f[i][j]);
			putchar(' ');
		}
		putchar('\n');
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值