大致题意: 有(n)个球和(m)个筐,每个球可以放入给定的两个筐中的一个。现让你把所有球都放入筐中,问最少有多少个筐有奇数个球。
大致思路
考虑对于能放入一个筐中的两个球,如果我们把它们一起放入,就不会改变筐中球数的奇偶性,不会影响答案。
用图论的方式来表示,就是在所有能放入同一个筐中的两个球之间连边,然后求出最大匹配,无法匹配的点就会对答案造成贡献。
这样似乎非常完美,然而,(nle2 imes10^5),显然不是带花树能跑得动的。。。
实际上,这张图是非常特殊的,每个连通块必然能够取到理论上的最大匹配,因此只要求出有多少个联通块大小为奇数即可。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 200000
using namespace std;
int n,m,s[N+5],t[N+5],f[N+5];I int fa(CI x) {return f[x]?f[x]=fa(f[x]):x;}
I void Union(RI x,RI y) {(x=fa(x))^(y=fa(y))&&(f[x]=y);}//合并
int main()
{
RI i,x;for(scanf("%d%d",&n,&m),i=1;i<=n;++i)
scanf("%d",&x),s[x]?Union(i,s[x]),0:s[x]=i,//对于每个筐记下第一个球,其余球与它合并
scanf("%d",&x),s[x]?Union(i,s[x]),0:s[x]=i;//同上
for(i=1;i<=n;++i) ++t[fa(i)];//统计连通块大小
RI ans=0;for(i=1;i<=n;++i) !f[i]&&t[i]&1&&++ans;//统计答案
return printf("%d
",ans),0;
}