题解 P3386 【【模板】二分图匹配】
首先呢声明一下,本宝宝发这篇题解只是为了(goto a;)
个人还是比较喜欢跑dinic暴力跑最大流。。。竟然比匈牙利还快。。
如果说不懂网络流的~~蒟蒻~~大佬们。
可以看看这个(反正我就是在这篇文章看懂的)
好啦,言归正传。
a:本宝宝想解释一下为什么这道题可以用网络流水过233....
首先我们看看二分图的概念。标准概念是:
简单的说,一个图被分成了两部分,相同的部分没有边,那这个图就是二分图,二分图是特殊的图。(摘自这里)
如果你看不懂的话,那么请看某大佬给宝宝讲的时候的解释:
~~一群汉子和一群妹子匹配。没有基友也没百合,不能开后宫,这就是二分图。最大匹配就是求能组成的CP最多多少对~~ 可能题解不过就是因为这句话233(逃~)
网络流最重要的是要建图!建图!建图!那么看看这道题怎么建图。
我们发现对于左边的n个点和右边的m个点。如果说最好的情况下。匹配的~~个~~对数是$min(m,n)$也就是说,我们左边尽可能的通过已有的边流到右半部分统计一下流到右半部分的容量最大值就是答案了(当然是要边的容量都是1的时候最简单了)。
所以我们将源点S设在左半部分左边,向左边所有的点连一条容量为1的边。汇点T设在右半部分的右边。从所有的右半部分的点连向汇点一条容量为1的边,暴力跑一边dicnic就好啦。
所以建边代码:
scanf("%d%d%d",&n1,&m1,&e1);
n=n1+m1+;//源点编号为1,汇点编号为总点数+1
for(int i=;i<=n1;i++)
{
add(,i+,);//空过源点,所以i+1,这里在连接源点和左部点。
add(i+,,);
}
for(int i=;i<=e1;i++)
{
int u,v;//连已有的边
scanf("%d%d",&u,&v);
if(u<=n1&&v<=m1)
add(u+,v+n1+,),
add(v+n1+,u+,);
}
for(int i=;i<=m1;i++)
{
add(i+n1+,n,);//连右部点和汇点
add(n,i+n1+,);
}
好啦完整代码奉上:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int cnt=;
int alist[];
struct data{
int v;int next;int value;
}edge[];
void add(int u,int v,int value)
{
edge[cnt].v=v;
edge[cnt].value=value;
edge[cnt].next=alist[u];
alist[u]=cnt++;
return ;
}
int h[];
int q[];
//dicnic暴力参见上面提到的博客。
bool bfs()
{
int x,next;
memset(h,-,sizeof(h));
int head=,tail=;
q[head]=;
h[]=;
while(head<tail)
{
x=q[head++];
next=alist[x];
while(next)
{
int v=edge[next].v;
int value=edge[next].value;
if(value&&h[v]<)
{
q[tail++]=v;
h[v]=h[x]+;
}
next=edge[next].next;
}
}
// for(int i=1;i<=n*m;i++) printf("h[%d]=%d\n",i,h[i]);
if(h[n]==-) return false;
return true;
}
int ans;
int dfs(int x,int y)
{
if(x==n) return y;
int next=alist[x];
int w,used=;
while(next)
{
int v=edge[next].v;
int value=edge[next].value;
if(value&&h[v]==h[x]+)
{
w=y-used;
w=dfs(v,min(w,value));
edge[next].value-=w;
edge[next^].value+=w;
used+=w;
if(used==y) return y;
}
next=edge[next].next;
}
if(!used) h[x]=-;
return used;
}
void dinic()
{
while(bfs()) ans+=dfs(,0x7fffffff);
}
int n1,m1,e1;
int main()
{
// freopen("testdata.in","r",stdin);
//第一遍没A就是因为忘了删上面这句话。。。
scanf("%d%d%d",&n1,&m1,&e1);
n=n1+m1+;
for(int i=;i<=n1;i++)
{
add(,i+,);
add(i+,,);
}
for(int i=;i<=e1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(u<=n1&&v<=m1)
add(u+,v+n1+,),
add(v+n1+,u+,);
}
for(int i=;i<=m1;i++)
{
add(i+n1+,n,);
add(n,i+n1+,);
}
dinic();//暴力跑最大流
printf("%d",ans);
return ;//程序拜拜
}
好啦这道题就先这样。对于要刷网络流的大佬们要是想练一练怎么见图的话P1402是一个很好的选择。
然后想深入学习的同学可以看看最小割和转对偶图。之后做一下P4001
题解 P3386 【【模板】二分图匹配】的更多相关文章
- [洛谷P3386] [模板] 二分图匹配 (匈牙利算法)
题目传送门 毒瘤出题人zzk出了个二分图匹配的题(18.10.04模拟赛T2),逼我来学二分图匹配. 网络流什么的llx讲完之后有点懵,还是匈牙利比较好理解(绿与被绿). 对于左边的点一个一个匹配,记 ...
- 【洛谷 p3386】模板-二分图匹配(图论)
题目:给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数. 解法:匈牙利算法.(以前我总是不记得......)实质上应该有贪心的思想,每次都尽量匹配,找到能和自己匹配的也尽量让它们匹配 ...
- 模板——二分图匹配KM
具体方法就不介绍了,详见 https://blog.csdn.net/sixdaycoder/article/details/47720471 主要讲一些注意点: 1:不直接将未匹配的y减小是因为要保 ...
- 【BZOJ1562】【NOI2009】变换序列(二分图匹配)
[BZOJ1562][NOI2009]变换序列 题面 BZOJ 洛谷 这题面写的是真的丑,还是先手动翻译成人话. 让你构造一个\(0..N-1\)的排列\(T\) 使得\(Dis(i,T_i)\)为给 ...
- P3386 【模板】二分图匹配(匈牙利&最大流)
P3386 [模板]二分图匹配 题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正 ...
- 洛谷—— P3386 【模板】二分图匹配
P3386 [模板]二分图匹配(复习) 题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每 ...
- luogu P3386 【模板】二分图匹配
二次联通门 : luogu P3386 [模板]二分图匹配 /* luogu P3386 [模板]二分图匹配 最大流 设置源点,汇点,连到每条边上 跑一边最大流即可 */ #include <i ...
- P3386 【模板】二分图匹配
题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...
- AC日记——【模板】二分图匹配 洛谷 P3386
题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...
- 洛谷 P3386 【模板】二分图匹配
题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...
随机推荐
- java成神之——注释修饰符
注释修饰符 自定义注释 元注释 通过反射在runtime访问注释 内置注释 多注释实例 错误写法 使用容器改写 使用@Repeatable元注释 注释继承 使用反射获取注释 获取类的注释 获取方法的注 ...
- C++深度解析教程学习笔记(4)C++中的新成员
1. 动态内存分配 (1)C++通过 new 关键字进行动态内存申请,是以类型为单位来申请空间大小的 (2)delete 关键字用于内存释放 ▲注意释放数组时要加[],否则只释放这个数组中的第 1 个 ...
- Django中间件限制用户访问频率
原:https://blog.csdn.net/weixin_38748717/article/details/79095399 一.定义限制访问频率的中间件 common/middleware.py ...
- consul watch
consul watch -type key -key mhc ./key_handler.py [root@mhc consul]# cat key_handler.py #!/usr/bin/py ...
- Screen - BOM对象
Screen 对象 Screen 对象包含有关客户端显示屏幕的信息. 注释:没有应用于 screen 对象的公开标准,不过所有浏览器都支持该对象. Screen 对象属性 属性 描述 availHei ...
- FZU2282 Wand
题意 n个数字,要求至少k个数字位置不变,其余进行错排的方案数 分析 错排公式: D(n)=(n-1)[D(n-2)+D(n-1)] 如果n个数字,i个数字位置不变,其余进行错排的的方案数是C(n, ...
- 刷题向》关于第一篇状压DP BZOJ1087 (EASY+)
这是本蒟蒻做的第一篇状压DP,有纪念意义. 这道题题目对状压DP十分友善,算是一道模板题. 分析题目,我们发现可以用0和1代表每一个格子的国王情况, 题目所说国王不能相邻放置,那么首先对于每一行是否合 ...
- Unity ios、android、pc一键打包(一)
http://www.cnblogs.com/miaoshujiang/p/5289223.html http://blog.csdn.net/ynnmnm/article/details/36774 ...
- Extend volumn in ubuntu 14.04
运行环境: ubuntu 14.04, VMware12.5.7 1. VMware上点击 虚拟机->设置->硬盘(SCSI)->扩展选项,设置自己希望的ubuntu磁盘运行空间大小 ...
- Linux下DNS配置
一.本机DNS配置 参考:http://blog.sina.com.cn/s/blog_68d6e9550100k3b7.html 二.DNS服务器搭建 http://toutiao.com/i631 ...