https://www.lydsy.com/JudgeOnline/problem.php?id=4405

这道题大概就是考场上想不出来,想出来也调不出来的题。

把每个桶拆成三个互相有边的点,每个球向它连接的桶的三个点分别连边。

0球1桶,匹配数为1;1球1桶,匹配数为2;2球一桶,匹配数为2;3球一桶,匹配数为3;

发现每种半桶的情况下匹配数都比该桶中放的球数大1,那么ans=最大匹配数-球数。

带花树找lca的时候,记得是用每个点的总父亲找。带花树的细节真是恶心人。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define LL long long
const int maxn=;
const int maxm=;
int n,m,siz;
struct nod{
int y,next;
}e[maxn];int head[maxm]={},tot=;
int q[maxn]={},tl,tr;
int bel[maxm]={},tly,d[maxm]={},pre[maxm]={},tp[maxm]={},fa[maxm]={};
inline void init(int x,int y){e[++tot].y=y;e[tot].next=head[x];head[x]=tot;}
inline int getfa(int x){
return fa[x]==x?x:fa[x]=getfa(fa[x]);
}
inline int lca(int x,int y){
++tly;
for(;;){
if(x){
x=getfa(x);
if(bel[x]==tly)return x;
else{bel[x]=tly;x=pre[d[x]];}
}swap(x,y);
}
}
inline void mlink(int x,int y,int pa){
while(getfa(x)!=pa){
pre[x]=y;y=d[x];
if(tp[y]==){tp[y]=;q[++tr]=y;}
if(getfa(x)==x)fa[x]=pa;
if(getfa(y)==y)fa[y]=pa;
x=pre[y];
}
}
int doit(int s){
for(int i=;i<=siz;++i)fa[i]=i;
memset(tp,,sizeof(tp));memset(pre,,sizeof(pre));
tl=tr=;q[]=s;tp[s]=;
while(tl<=tr){
int x=q[tl];++tl;
for(int i=head[x];i;i=e[i].next){
int y=e[i].y;
if(getfa(y)==getfa(x)||tp[y]==)continue;//cout<<i<<endl;
if(!tp[y]){
tp[y]=;pre[y]=x;//cout<<y<<endl;
if(!d[y]){
for(int now=y,j,las;now;now=las){
j=pre[now];las=d[pre[now]];
d[j]=now;d[now]=j;
}//cout<<i<<1<<endl;
return ;
}
tp[d[y]]=;q[++tr]=d[y];
}
else{
int pa=lca(x,y);
mlink(x,y,pa);mlink(y,x,pa);
}
}
}
return ;
}
int main(){
int T;scanf("%d",&T);
while(T-->){
memset(bel,,sizeof(bel));memset(d,,sizeof(d));
memset(head,,sizeof(head));
tot=tly=;
int p;
scanf("%d%d%d",&n,&m,&p);siz=n+m*;
int x,y;
for(int i=;i<=m;++i){
init(i,i+m);init(i+m,i);
init(i,i+m*);init(i+m*,i);
init(i+m,i+m*);init(i+m*,i+m);
}
for(int i=;i<=p;++i){
scanf("%d%d",&x,&y);
init(m*+x,y);init(y,m*+x);
init(m*+x,y+m);init(y+m,m*+x);
init(m*+x,y+m*);init(y+m*,m*+x);
}
int ans=;
for(int i=;i<=siz;++i)if(!d[i])ans+=doit(i);
printf("%d\n",ans-n);
}
return ;
}

BZOJ 4405 [wc2016]挑战NPC 带花树 一般图最大匹配的更多相关文章

  1. [BZOJ]4405: [wc2016]挑战NPC(带花树)

    带花树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...

  2. bzoj 4405: [wc2016]挑战NPC【带花树】

    把每个筐子拆成3个,分别表示放0/1/2个,然后把这三个点两两连起来,每一个可以放在筐里的球都想这三个点连边. 这样可以发现,放0个球的时候,匹配数为1,放1个球的时候,匹配数为1,放2个球的时候,匹 ...

  3. 【Learning】带花树——一般图最大匹配

    一般图最大匹配--带花树 问题 ​ 给定一个图,求该图的最大匹配.即找到最多的边,使得每个点至多属于一条边. ​ 这个问题的退化版本就是二分图最大匹配. ​ 由于二分图中不存在奇环,偶环对最大匹配并无 ...

  4. [WC2016]挑战NPC(一般图最大匹配)

    [WC2016]挑战NPC(一般图最大匹配) Luogu 题解时间 思路十分有趣. 考虑一个筐只有不多于一个球才有1的贡献代表什么. 很明显等效于有至少两个位置没有被匹配时有1的贡献. 进而可以构造如 ...

  5. [bzoj4405][wc2016]挑战NPC

    来自FallDream的博客,未经允许,请勿转载,谢谢. 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个球,用整数1到n编号.还有m个筐子,用整数1到m编号. ...

  6. [WC2016]挑战NPC

    Sol 这做法我是想不到\(TAT\) 每个筐子拆成三个相互连边 球向三个筐子连边 然后跑一般图最大匹配 这三个筐子间最多有一个匹配 那么显然每个球一定会放在一个筐子里,一定有一个匹配 如果筐子间有匹 ...

  7. [UOJ171][WC2016]挑战NPC

    uoj luogu bzoj sol 你可以列一个表格. 一个框子里放球的数量 0 1 2 3 对"半空框子"数量的贡献 1 1 0 0 把一个框子拆三个点.两两之间连边. 会发现 ...

  8. ZOJ 3316 Game 一般图最大匹配带花树

    一般图最大匹配带花树: 建图后,计算最大匹配数. 假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点.后手不论怎么走,都必定走到一个被匹配的点上.先手就能够顺着这个交错路走下去,最后一定是后 ...

  9. 【BZOJ4405】【WC2016】挑战NPC(带花树)

    [BZOJ4405][WC2016]挑战NPC(带花树) 题面 BZOJ 洛谷 Uoj Description 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个 ...

随机推荐

  1. Window和document的区别

    1.window 窗口对象.就是可视化区域的大小,不包含滚动条内东东. 2.document 对象,包含滚动条以外的区域

  2. 【逆向工具】逆向工具101editor使用-游戏快速通关

    [渡者游戏简介] 船夫小江将运送客人的,羊.狐狸.草等物品过河,如果留下动物被其它种类吃掉任务就失败了.你需要帮助他做出正确的顺序选择.Ferryman是一款根据经典谜题改编的解谜游戏. 一.查看文件 ...

  3. 为caffe添加最简单的全通层AllPassLayer

    参考赵永科的博客,这里我们实现一个新 Layer,名称为 AllPassLayer,顾名思义就是全通 Layer,“全通”借鉴于信号处理中的全通滤波器,将信号无失真地从输入转到输出. 虽然这个 Lay ...

  4. 董事局主席董事长总裁首席执行官CEO总裁董事监事区别

    董事长是公司的最大股东:董事长是董事会的主席,一般是企业的所有者,掌握企业的股权并且决定企业的发展策略. 董事局主席通常是在大财团中才会出现,董事局主席管数个董事长,一个大财团涉及很多方面的业务,因此 ...

  5. 【ES】代码例子

    #!/usr/bin/env python #coding=utf-8 from elasticsearch import Elasticsearch from elasticsearch_dsl i ...

  6. python+selenium+unittest 实现自动化测试

    示例代码: baidu.py import csv #导入csv模块 from itertools import islice #从itertools导入islice,后边让其默认跳过第一行使用 fr ...

  7. android Unable to inflate view tag without class attribute

    定位 到 问题 是 布局文件出错,   Unable to inflate view tag without class attribute 错误 原因 <view android:layout ...

  8. [Reprinted] 使用Spring Data Redis操作Redis(一) 很全面

    Original Address: http://blog.csdn.net/albertfly/article/details/51494080

  9. Zbrush Topogun 备忘

    ====Zbrush==== 1.按住shift 在空白地方移动鼠标左键 就会去到正交视图 2.shift+F可以看一下布线的情况 3.按住shift 点一下画布,松开shift键,就可以旋转画布 4 ...

  10. Python list 函数

    list 修改列表元素: 下标直接修改  list[下标]=值 列表添加元素: list.append(值)末尾追加 列表插入元素: list.insert(下标,元素) 列表删除元素: del li ...