L i n k Link Link
l u o g u P 5994 luogu\ P5994 luogu P5994
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
5
1 2 3 4 5
4 3 2 1
3 4 5
2 1
5
S a m p l e Sample Sample O u t p u t Output Output
7
H i n t Hint Hint
T r a i n Train Train o f of of T h o u g h t Thought Thought
要知道一个杯子是否有球,那么我们就要知道这个杯子的奇偶性
那就有两种方法:
1.直接查询
c
i
,
i
c_{i,i}
ci,i
2.查出所在区间的奇偶性即
c
i
,
i
=
c
i
,
j
−
c
j
,
k
c_{i,i} = c_{i,j} - c_{j,k}
ci,i=ci,j−cj,k
那我们可以跑一遍最小生成树得出答案
C o d e Code Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int n, h, t, x, y, p, f[10001];
ll ans, z;
struct awsl
{
int to, from;
ll val;
}w[10000001];
int find(int x)
{
if (f[x] == x) return x;
return f[x] = find(f[x]);
}
bool cmp(awsl a, awsl b)
{return a.val < b.val;}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; f[i] = i, ++i)
for (int j = i; j <= n; ++j)
{
scanf("%lld", &z);
w[++t] = (awsl){i - 1, j, z};
w[++t] = (awsl){j, i - 1, z};
}
sort(w + 1, w + t + 1, cmp);
h = 1; p = 1;
while (h <= t && p <= n) {
x = w[h].to, y = w[h].from, z = w[h].val;
if (find(x) != find(y)) {//还不在一个连通块
++p;
ans += z;//累计答案
f[find(x)] = find(y);
}
++h;
}
printf("%lld", ans);
return 0;
}