BZOJ 2139 road(构造,最小生成树)BZOJ 修复工程

Posted 繁凡さん

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2139 road(构造,最小生成树)BZOJ 修复工程相关的知识,希望对你有一定的参考价值。

整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


题目链接

https://hydro.ac/d/bzoj/p/2139

hydro 的 BZOJ 修复工程 !(我也去领了一点题慢慢修着玩,这题就是我修的嘿嘿嘿)

题目描述

很久很久以前,中原地区分成了 N N N 个国家,编号为 1 ∼ N 1\\sim N 1N,任意两个国家都可互达。每个国家有一个攻击值 A i A_i Ai 和防御值 B i B_i Bi 。定义一个人从 i i i 国去 j j j 国的危险值为:假如 A i > B j A_i>B_j Ai>Bj ,则危险值为 A i 2 − B j 2 A_i^2-B_j^2 Ai2Bj2,否则危险值为 0 0 0 。现在,Nan从国家 1 1 1 出发,经过每一个国家有且仅有一次,最后回到国家 1 1 1 ,要求找出一种方案,使得其中危险值的最大值最小。

输入格式

第一行正整数 N N N ,表示有 N N N 个国家;

第二行正整数 A 1 , A 2 , x , y , z A_1,A_2,x,y,z A1,A2,x,y,z,有等式 A i = ( x × A i − 1 + y × A i − 2 + z ) m o d    32767 A_i=(x\\times A_{i-1}+y\\times A_{i-2}+z)\\mod 32767 Ai=(x×Ai1+y×Ai2+z)mod32767

第三行正整数 B 1 , B 2 , x , y , z B_1,B_2,x,y,z B1,B2,x,y,z,有等式 B i = ( x × B i − 1 + y × B i − 2 + z ) m o d    32767 B_i=(x\\times B_{i-1}+y\\times B_{i-2}+z)\\mod 32767 Bi=(x×Bi1+y×Bi2+z)mod32767

输出格式

输出一个数,表示危险值的最大值最小是多少。

5
2 4 1231 4432 123
123 45 3245 555 6676
9171832

数据规模与约定

对于 100 % 100\\% 100% 的数据, N ≤ 1 0 6 N\\le 10^6 N106

提示

样例说明:

A数组为 2 , 4 , 13911 , 5151 , 3031 2,4,13911,5151,3031 2,4,13911,5151,3031
B数据为 123 , 45 , 24364 , 26060 , 21765 123,45,24364,26060,21765 123,45,24364,26060,21765
其中一种最优方案为 1 − 2 − 4 − 3 − 5 − 1 1- 2- 4- 3- 5-1 124351,危险值分别为 0 , 0 , 0 , 0 , 9171832 0,0,0,0,9171832 0,0,0,0,9171832

Solution

解题思路来源:https://www.cnblogs.com/Apocrypha/p/9574196.html
但这个思路总感觉不太对劲()至少我太不会证明

根据题目中权值的特殊要求,我们显然在连边的时候,一定是尽量减少两点间 a a a b b b 之间的差距,每个点有 a a a b b b 两个信息,而题目中要求的是 最大值最小,并求出这个最小值。

所以我们只需要把这个图建出来,取图中所有边的最小值即可。考虑最大值最小,显然我们将 a a a b b b 之间的差值均衡分配一下即可。即 a a a b b b 按照从小到大的顺序排序,然后 a i a_i ai b i b_i bi 相连。

这样整张图就变成了一个最大值最小的,由若干个环组成的图。

将这些环连通即可。边取最小值使得图连通,显然就是最小生成树。我们考虑构图,继续均衡差值,将 a i a_i ai b i − 1 b_i-1 bi1 再次相连,求最小生成树,途中使用的边中取最大值即可。

Code

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
const int maxn = 1e6 + 7;
const int p = 32767;

struct node
{
	ll v;
	int id;
	bool operator < (const node &t) const {
		return v < t.v;
	}
}a[maxn], b[maxn], c[maxn];

int n, m, s, t, x, y, z;
int fa[maxn];
ll ans;

int Find(int x)
{
	if(fa[x] == x) return x;
	return fa[x] = Find(fa[x]);
}

int main()
{
	scanf("%d%lld%lld%d%d%d", &n, &a[1].v, &a[2].v, &x, &y, &z);
	
	for (int i = 3; i <= n; ++ i) 
		a[i].v = (1ll * x * a[i - 1].v % p + 1ll * y * a[i - 2].v % p + z) % p;
	scanf("%lld%lld%d%d%d", &b[1].v, &b[2].v, &x, &y, &z);
	for (int i = 3; i <= n; ++ i)
		b[i].v = (1ll * x * b[i - 1].v % p + 1ll * y * b[i - 2].v % p + z) % p;
	for (int i = 1; i <= n; ++ i)
		a[i].id = b[i].id = i;
	sort(a + 1, a + 1 + n);
	sort(b + 1, b + 1 + n);
 
	for (int i = 1; i <= n; ++ i)
		fa[i] = i;
	
	for (int i = 1; i <= n; ++ i) {
		int fx = Find(a[i].id);
		int fy = Find(b[i].id);
		if(a[i].id == b[i].id) continue;
		fa[fx] = fy;
		ans = max(ans, a[i].v * a[i].v - b[i].v * b[i].v);
	}
	for (int i = 2; i <= n; ++ i)
		c[i - 1] = (node){a[i].v * a[i].v - b[i - 1].v * b[i - 1].v, i};
	sort(c + 1, c + n);
	for (int i = 1; i < n; ++ i) {
		int fx = Find(a[c[i].id].id);
		int fy = Find(b[c[i].id - 1].id); 
		if(fx != fy) { 
			fa[fx] = fy;
			ans = max(ans, c[i].v);
		}
	}
	cout << ans << endl;
	return 0;
}

以上是关于BZOJ 2139 road(构造,最小生成树)BZOJ 修复工程的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1626 [Usaco2007 Dec]Building Roads 修建道路:kruskal(最小生成树)

bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路最小生成树

bzoj 1626: [Usaco2007 Dec]Building Roads 修建道路 -- 最小生成树

POJ1251 Jungle Roads最小生成树

HDU 4081Qin Shi Huang&#39;s National Road System(最小生成树+最小瓶颈路)

HDU-1102 Constructing Roads ( 最小生成树 )