UOJ 171 【WC2016】挑战NPC
一开始还真没想到是一般图匹配这种模型(毕竟才会的带花树)
把每一个盒子拆成3个,每一个可以放置进它的小球分别向这三个点连边,然后这三个点在连成一个三元环,最终答案就是小球数目-匹配数。
由于是一般图,所以套一个带花树就可以了。
NOTICE:寻找增广路时,应该从球先找起,这样子才保证了每个球有地方放置。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 10010
#define llg long long
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,sett,father[maxn],pre[maxn],match[maxn],vis[maxn],id[maxn],dl[maxn*],head,tail,ans,T,totn,e;
llg c[][]; vector<llg> a[maxn]; llg find(llg x){if (father[x]!=x) father[x]=find(father[x]); return father[x];} llg lca(llg x,llg y)
{
sett++;
while (vis[x]!=sett)
{
if (x)
{
x=find(x);
if (vis[x]==sett) return x;
vis[x]=sett;
if (match[x]!=) x=find(pre[match[x]]);
else x=;
} swap(x,y);
}
return x;
} void change(llg x,llg y,llg fa)
{
llg z;
while (find(x)!=fa)
{
pre[x]=y; z=match[x];
if (id[z]==) {id[z]=,dl[++tail]=z;}
if (find(z)==z) father[z]=fa;
if (find(x)==x) father[x]=fa;
y=z; x=pre[y];
}
} bool bfs(llg p)
{
llg x,w,v;
for (llg i=;i<=n;i++) id[i]=-,father[i]=i;
head=,tail=,dl[]=p; id[p]=;
do
{
x=dl[++head],w=a[x].size();
for (llg i=;i<w;i++)
{
v=a[x][i];
if (id[v]==-)
{
pre[v]=x;
id[v]=;
if (!match[v])
{
llg last,t,now=v;
while (now!=)
{
t=pre[now],last=match[t];
match[t]=now; match[now]=t;
now=last;// v=t;
}//把原lai的匹配和非匹配bian取反
return ;
}
id[match[v]]=,dl[++tail]=match[v];
}
else
if (id[v]== && find(v)!=find(x))
{
llg dad=lca(x,v);
change(x,v,dad);
change(v,x,dad);
}
}
}while (head!=tail);
return ; } void link(llg x,llg y) {a[x].push_back(y),a[y].push_back(x);} void init()
{
for (llg i=;i<=n;i++) a[i].clear(),vis[i]=match[i]=pre[i]=father[i]=id[i]=dl[i]=;
//for (llg i=1;i<=n;i++) for (llg j=1;j<=n;j++) c[i][j]=c[j][i]=0;
scanf("%lld%lld%lld",&n,&m,&e);
totn=n;
llg x,y;
for (llg i=;i<=e;i++)
{
scanf("%lld%lld",&x,&y); llg po=m*+x;
link(po,y*-),link(po,y*-),link(po,y*);
//a[x].push_back(y),a[y].push_back(x);
}
n=n+m*;
for (llg i=;i<=m;i++)
{
link(i*-,i*-),link(i*-,i*),link(i*,i*-);
}
} void oupt()
{
cout<<ans-totn<<endl;
for (llg i=;i<=totn;i++)
{
printf("%lld ",(match[*m+i]-)/+);
}
printf("\n");
} int main()
{
//yyj("a");
cin>>T;
while (T--)
{
ans=;
init();
for (llg i=n;i>;i--)
if (!match[i] && bfs(i)) ans++;
oupt();
}
return ;
}
UOJ 171 【WC2016】挑战NPC的更多相关文章
- [WC2016]挑战NPC(一般图最大匹配)
[WC2016]挑战NPC(一般图最大匹配) Luogu 题解时间 思路十分有趣. 考虑一个筐只有不多于一个球才有1的贡献代表什么. 很明显等效于有至少两个位置没有被匹配时有1的贡献. 进而可以构造如 ...
- [UOJ171][WC2016]挑战NPC
uoj luogu bzoj sol 你可以列一个表格. 一个框子里放球的数量 0 1 2 3 对"半空框子"数量的贡献 1 1 0 0 把一个框子拆三个点.两两之间连边. 会发现 ...
- [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个 ...
随机推荐
- vue学习之五生命周期
一.vue生命周期图解 下图展示了实例的生命周期.你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高. 二.vue钩子函数使用 2.1beforeCreate 在实例初始 ...
- java8,方法引用
1:方法引用,https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html 当我们使用lambda表达式去创建一个 ...
- tf.nn.embedding_lookup函数的用法
关于np.random.RandomState.np.random.rand.np.random.random.np.random_sample参考https://blog.csdn.net/lanc ...
- PAT 1028 List Sorting[排序][一般]
1028 List Sorting (25)(25 分) Excel can sort records according to any column. Now you are supposed to ...
- nodejs加WebSocket,聊天工具
1.WebSocket必须要与服务器连接,所以这里采用node起服务,这里用到了ws,,也有人用nodejs-websocket 2.首先 npm install ws 3.新建一个server.js ...
- keras之save & reload model
import numpy as np np.random.seed(1337) # for reproducibility from keras.models import Sequential fr ...
- 015-awk
1.awk的处理方式: 一次处理一行. 对每行可以进行切片处理,针对字段处理.2.awk的格式: awk BEGIN{循环之前初始化} [options] 'command' END{循环之后结尾} ...
- python爬虫对于gb2312
对于刚刚接触python爬虫的人,常常会碰到一个比较烦的问题, 如果网页是GB2312编码格式,我们直接decode(’GB2312‘)一般python都会报错: GB2312不能编码该页面. 这就比 ...
- 形象易懂讲解算法I——小波变换
https://zhuanlan.zhihu.com/p/22450818?refer=dong5 最早发于回答:能不能通俗的讲解下傅立叶分析和小波分析之间的关系? - 咚懂咚懂咚的回答现收入专栏. ...
- sift 与 surf 算法
http://blog.csdn.net/cy513/article/details/4414352 SURF算法是SIFT算法的加速版,OpenCV的SURF算法在适中的条件下完成两幅图像中物体的匹 ...