• 【BZOJ4874】筐子放球(特殊的一般图最大匹配)


    点此看题面

    大致题意:(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;
    }
    
  • 相关阅读:
    Minimum Sum
    Prefix and Suffix
    BBuBBBlesort!
    Wanna go back home
    The Chosen One+高精度
    一元三次方程
    文本文件比对
    nginx日志文件切割
    nginx启动脚本
    nginx
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ4874.html
Copyright © 2020-2023  润新知