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 1∼N,任意两个国家都可互达。每个国家有一个攻击值 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 Ai2−Bj2,否则危险值为 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×Ai−1+y×Ai−2+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×Bi−1+y×Bi−2+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 N≤106
提示
样例说明:
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
1−2−4−3−5−1,危险值分别为
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 bi−1 再次相连,求最小生成树,途中使用的边中取最大值即可。
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 修建道路 -- 最小生成树
HDU 4081Qin Shi Huang's National Road System(最小生成树+最小瓶颈路)