正题

题目链接:https://www.luogu.com.cn/problem/P4258


题目大意

给出\(n\)个球,\(m\)个篮筐,每个球都可以被放入一些特定的篮筐,每个球都要放,要求球的个数小于等于\(1\)的篮筐数量最多。

保证有解,输出方案。

\(1\leq T\leq 5,1\leq n\leq 3m,1\leq m\leq 100\)


解题思路

额其实做题之前已经知道正解是带花树就简单很多了。

每个篮筐我们开一个三个点的环,那么如果环上大于一个点呗匹配掉了那么这个环内就无法匹配了。

又因为一定有解所以肯定不会因为环上的匹配使答案更劣,所以这样匹配出来的结果为\(ans\)那么答案就是\(ans-n\)。

但是有一个问题我们发现这样跑的话每个球不一定都是匹配点,这样会影响我们输出方案。因为我们是找增广路的做法,这种做法不会减少已经匹配了的点,所以我们如果优先跑球代表的点就不会有问题了。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1010,M=2e5+10;
struct node{
int to,next;
}a[M<<1];
int cnt,tot,T,n,m,e,ans,ls[N];
int dfn[N],pre[N],fa[N],match[N],tag[N];
queue<int> q;
void addl(int x,int y){
a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;
return;
}
int find(int x)
{return (fa[x]==x)?(x):(fa[x]=find(fa[x]));}
int LCA(int x,int y){
++cnt;x=find(x);y=find(y);
while(dfn[x]!=cnt){
dfn[x]=cnt;
x=find(pre[match[x]]);
if(y)swap(x,y);
}
return x;
}
void Blossom(int x,int y,int lca){
while(find(x)!=lca){
pre[x]=y;y=match[x];
if(tag[y]==2){tag[y]=1;q.push(y);}
fa[x]=fa[y]=lca;x=pre[y];
}
return;
}
int Agu(int s){
memset(tag,0,sizeof(tag));
memset(pre,0,sizeof(pre));
for(int i=1;i<=3*m+n;i++)fa[i]=i;
while(!q.empty())q.pop();
q.push(s);tag[s]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(!tag[y]){
tag[y]=2;pre[y]=x;
if(!match[y]){
for(int u=y,lst;u;u=lst)
lst=match[pre[u]],match[u]=pre[u],match[pre[u]]=u;
return 1;
}
tag[match[y]]=1;q.push(match[y]);
}
else if(tag[y]==1&&find(x)!=find(y)){
int lca=LCA(x,y);
Blossom(x,y,lca);
Blossom(y,x,lca);
}
}
}
return 0;
}
int main()
{
scanf("%d",&T);
while(T--){
tot=ans=0;
memset(ls,0,sizeof(ls));
memset(match,0,sizeof(match));
scanf("%d%d%d",&n,&m,&e);
for(int i=1;i<=m;i++)
addl(i*3-2,i*3-1),addl(i*3-1,i*3),addl(i*3,i*3-2);
for(int i=1;i<=e;i++){
int x,y;
scanf("%d%d",&x,&y);
addl(x+3*m,y*3);
addl(x+3*m,y*3-1);
addl(x+3*m,y*3-2);
}
for(int i=n+3*m;i>=1;i--)
if(!match[i])ans+=Agu(i);
printf("%d\n",ans-n);
for(int i=1;i<=n;i++)
printf("%d ",1+(match[3*m+i]-1)/3);
putchar('\n');
}
return 0;
}

P4258-[WC2016]挑战NPC【带花树】的更多相关文章

  1. BZOJ 4405 [wc2016]挑战NPC 带花树 一般图最大匹配

    https://www.lydsy.com/JudgeOnline/problem.php?id=4405 这道题大概就是考场上想不出来,想出来也调不出来的题. 把每个桶拆成三个互相有边的点,每个球向 ...

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

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

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

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

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

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

  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. 【BZOJ4405】【WC2016】挑战NPC(带花树)

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

  9. 「WC2016」挑战NPC

    「WC2016」挑战NPC 解题思路 这个题建图非常厉害,带花树什么的只会口胡根本写不动,所以我写了机房某大佬教我的乱搞. 考虑把一个筐 \(x\) 拆成 \(x1,x2,x3\) 三个点,且这三个点 ...

随机推荐

  1. 玩转Spring生命周期之Lifecycle

    Lifecycle callbacks Initialization callbacks.Destruction callbacks要与容器的bean生命周期管理交互,即容器在启动后和容器在销毁前对每 ...

  2. Linux命令全训练

    一.实验目的 为后续上机实验做准备,熟悉常用的Linux操作. 二.实验平台 操作系统:Ubuntu14.04 三.实验内容和要求 1.Linux系统中的常用快捷键 Tab 自动补全 上下箭头 显示历 ...

  3. request库的简单使用

    7种基本用法 首先安装requests库 如果你本地只有一个python环境直接运行pip install requests 像我本地装了3个不同的python怎么使你安装在你想要安装的python下 ...

  4. 输入URL后浏览器的过程

    In this article, I want my readers to get a picture of a very basic concept of the web world. Previo ...

  5. mzy git学习,分支冲突,以及冲突解决(五)

    冲突解决: 先尝试制造冲突: 首先我:git checkout -b mzy 创建一个mzy的分支 然后在其中修改readme.txt文件,随便加上一点东西. vim readme.txt   wri ...

  6. 微信支付 调用支付jsapi缺少参数total_fee 和 支付验证签名失败 prepay_id配置问题

    =======================================================先熟悉一下统一下单api所需要的参数=========================== ...

  7. Vulnhub靶机渗透 -- DC5

    信息收集 通过nmap搜索到IP为:192.168.200.11 开启了80http.111RPC服务端口 先打开网页,然后进行目录爆破 contact.php 攻击 经搜索没有发现可以攻击wheel ...

  8. Mac OS ssh 禁用密码登陆

    $ sudo vim /etc/ssh/sshd_config PubkeyAuthentication yes PasswordAuthentication no UsePAM no then: $ ...

  9. How to check type of files without extensions in python? 不通过文件扩展名,怎样知道文件类型?

    有一个命令 file 可以用 $ file fuck fuck.png: PNG image data, 1122 x 750, 8-bit colormap, non-interlaced pyth ...

  10. GitHub+JSDelivr+PicGo+Typora免费白嫖高速稳定图床

    0. 初衷1. 创建 GitHub 仓库2. 使用 jsDelivr 进行 CDN 加速3. 使用PicGo上传图片4. Typora 配置 PicGo 上传 0. 初衷 平时写文章,经常需要插入图片 ...