[UOJ171][WC2016]挑战NPC
sol
你可以列一个表格。
| 一个框子里放球的数量 | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 对“半空框子”数量的贡献 | 1 | 1 | 0 | 0 |
把一个框子拆三个点。两两之间连边。
会发现,如果这三个点里一个都没有被球匹配掉,那么这三个点的最大匹配数是\(1\);如果任意一个点被一个球匹配掉了,那么剩下两个点一定可以匹配,所以最大匹配数还是\(1\);有两个点或者是三个点被匹配后最大匹配就是\(0\)。
所以,按如上方式建图,每个球向它可以放进的框子对应的的三个点都连边。跑出最大匹配后输出\(ans-n\)就好了。(因为\(n\)个球是一定可以被匹配的)
update:yyb跟我说他在WA了若干次后发现了一件有趣的事情。
因为只有增广成功时才会修改匹配,所以如果先匹配框子再匹配球的话,不能保证球一定出现在最大匹配中,所以在输出方案的时候会出问题。
所以就一定要先匹配球再匹配框子。
code
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 1005;
int T,n,m,q,to[N*N],nxt[N*N],head[N],cnt;
int match[N],vis[N],pre[N],fa[N],tim[N],idx,ans;
queue<int>Q;
void link(int u,int v)
{
to[++cnt]=v;nxt[cnt]=head[u];
head[u]=cnt;
to[++cnt]=u;nxt[cnt]=head[v];
head[v]=cnt;
}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int lca(int x,int y)
{
for (++idx;;swap(x,y))
if (x)
{
x=find(x);
if (tim[x]==idx) return x;
else tim[x]=idx,x=pre[match[x]];
}
}
void blossom(int x,int y,int p)
{
while (find(x)!=p)
{
pre[x]=y;y=match[x];
if (vis[y]==2) vis[y]=1,Q.push(y);
if (find(x)==x) fa[x]=p;
if (find(y)==y) fa[y]=p;
x=pre[y];
}
}
int Aug(int S)
{
for (int i=n+3*m;i;--i)
vis[i]=pre[i]=0,fa[i]=i;
while (!Q.empty()) Q.pop();
Q.push(S);vis[S]=1;
while (!Q.empty())
{
int u=Q.front();Q.pop();
for (int e=head[u];e;e=nxt[e])
{
int v=to[e];
if (find(u)==find(v)||vis[v]==2) continue;
if (!vis[v])
{
vis[v]=2;pre[v]=u;
if (!match[v])
{
for (int x=v,lst;x;x=lst)
lst=match[pre[x]],match[x]=pre[x],match[pre[x]]=x;
return 1;
}
vis[match[v]]=1;Q.push(match[v]);
}
else
{
int gg=lca(u,v);
blossom(u,v,gg);blossom(v,u,gg);
}
}
}
return 0;
}
int main()
{
T=gi();
while (T--)
{
n=gi();m=gi();q=gi();cnt=idx=ans=0;
for (int i=n+3*m;i;--i) head[i]=match[i]=tim[i]=0;
for (int i=1;i<=q;++i)
{
int u=gi(),v=gi();
link(u+3*m,v),link(u+3*m,v+m),link(u+3*m,v+2*m);
}
for (int i=1;i<=m;++i)
link(i,i+m),link(i,i+2*m),link(i+m,i+2*m);
for (int i=n+3*m;i;--i) if (!match[i]) ans+=Aug(i);
printf("%d\n",ans-n);
for (int i=1+3*m;i<=n+3*m;++i) printf("%d ",(match[i]-1)%m+1);
puts("");
}
return 0;
}
[UOJ171][WC2016]挑战NPC的更多相关文章
- [WC2016]挑战NPC(一般图最大匹配)
[WC2016]挑战NPC(一般图最大匹配) Luogu 题解时间 思路十分有趣. 考虑一个筐只有不多于一个球才有1的贡献代表什么. 很明显等效于有至少两个位置没有被匹配时有1的贡献. 进而可以构造如 ...
- [BZOJ]4405: [wc2016]挑战NPC(带花树)
带花树模板 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...
- [bzoj4405][wc2016]挑战NPC
来自FallDream的博客,未经允许,请勿转载,谢谢. 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个球,用整数1到n编号.还有m个筐子,用整数1到m编号. ...
- BZOJ 4405 [wc2016]挑战NPC 带花树 一般图最大匹配
https://www.lydsy.com/JudgeOnline/problem.php?id=4405 这道题大概就是考场上想不出来,想出来也调不出来的题. 把每个桶拆成三个互相有边的点,每个球向 ...
- [WC2016]挑战NPC
Sol 这做法我是想不到\(TAT\) 每个筐子拆成三个相互连边 球向三个筐子连边 然后跑一般图最大匹配 这三个筐子间最多有一个匹配 那么显然每个球一定会放在一个筐子里,一定有一个匹配 如果筐子间有匹 ...
- bzoj 4405: [wc2016]挑战NPC【带花树】
把每个筐子拆成3个,分别表示放0/1/2个,然后把这三个点两两连起来,每一个可以放在筐里的球都想这三个点连边. 这样可以发现,放0个球的时候,匹配数为1,放1个球的时候,匹配数为1,放2个球的时候,匹 ...
- 「WC2016」挑战NPC
「WC2016」挑战NPC 解题思路 这个题建图非常厉害,带花树什么的只会口胡根本写不动,所以我写了机房某大佬教我的乱搞. 考虑把一个筐 \(x\) 拆成 \(x1,x2,x3\) 三个点,且这三个点 ...
- 【BZOJ4405】【WC2016】挑战NPC(带花树)
[BZOJ4405][WC2016]挑战NPC(带花树) 题面 BZOJ 洛谷 Uoj Description 小N最近在研究NP完全问题,小O看小N研究得热火朝天,便给他出了一道这样的题目: 有n个 ...
- UOJ171 【WC2016】挑战NPC
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
随机推荐
- Java底层代码实现多文件读取和写入
需求: "E:/data/"目录下有四个文件夹,如下: 每个文件夹下有几个.csv文件,如下: 将每个文件夹下的.csv文件合并成一个以该文件夹命名的.csv文件. 做法: 找到& ...
- OpenGL学习进程(4)第二课:绘制图形
本节是OpenGL学习的第二个课时,下面介绍如何用点和线来绘制图形: (1)用点的坐标来绘制矩形: #include <GL/glut.h> void display(void) ...
- 015_[小插曲]看黄老师《炼数成金Hadoop应用开发实战案例》笔记
1.大数据金字塔结构 Data Source-->Data Warehouses/Data Marts-->data exploration-->Data Mining-->D ...
- mybatis中collection和association的作用以及用法
deptDaoMapper.xml 部门对应员工(1对多的关系) <resultMap type="com.hw.entity.Dept" id="deptinfo ...
- python中的值传递和引用传递
Python中的变量是没有类型的,我们可以把它看做一个(*void)类型的指针,变量是可以指向任何对象的,而对象才是有类型的. Python中的对象有可变对象(number,string,tuple等 ...
- MACHINE_START-内核板级初始化实现机制(linux3.1.0)
转:https://blog.csdn.net/charliewangg12/article/details/41518549 在驱动开发时,我们都是以一块开发板为基础移植驱动程序.每一块开发板对应一 ...
- box-flex兼容写法
box-flex布局在这几年发生了多次变化,可分为2009版.2011版以及2013版, 区分: display:box(inline-box), box-{*}的格式为2009版 display:b ...
- WKWebview的基本使用
在开发过程中,iOS 中实现加载 web 页面主要有两种控件,UIWebView 和 WKWebview,两种控件对应具体的实现方法不同.WKWebView是苹果公司在iOS8系统推出的,这里主要概述 ...
- 字符串处理sdut 2411
题目:http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=2411 关于字符串处理的题,此题坑点很多w ...
- KestrelHttpServer
source code of Kestrel of documentation https://github.com/aspnet/KestrelHttpServer https://github.c ...