【学校OJ】二分图匹配 骑士共存问题
来源:互联网 发布:把网站生成app源码 编辑:程序博客网 时间:2024/05/21 05:39
题目描述
输入
输出
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
3 21 13 3
样例输出
5
由于没有绑定手机而苦逼了很久,所以为了补偿就来一篇吧。
二分图呢,就是这样一种图:可以把所有节点分成两个部分,x与y,而所有边必须是x连接到y,不允许x或y中出现自己连接的情况。而由于二分图的这种性质也是定义,就出现了一种问题——二分图的最大匹配。就是求二分图中选出尽可能多的边,让任意两条边不相连。有一种通俗的诠释:一群剩男剩女进行组成伴侣,在不同性恋、不一夫多妻、一妻多夫的情况下撮合尽可能多的情侣。
匈牙利算法就可以解决这种问题。具体操作是这样的:
1.寻找一个没有匹配的x节点(剩男),然后从它所有有边相连的(互相有感觉的)y节点中寻找一个同样没有匹配的(剩女),这时,将他们加入到匹配里面(撮合成一对),任务完成(撮合成功),再进行一遍1,直到无法进行1为止(没有剩男了~)。如果有边相连的y全部都在匹配中(没有两厢情愿的女孩子是单身),则对每一个相连的y进行2
2.将这个有边相连的(有男朋友的)y的x(男朋友)进行待定,如果x可以找到除了自己的其他空闲的y(有其他剩女可以选),那么将匹配关系变一变(小三上位,原配另找新欢),就多了一对匹配不是么?但如果同样没有找到怎么办?一样对所有相连的y进行2操作,直到多了一对匹配为止~如果找遍所有人都无法解决问题,很抱歉原来的这位x,你永远没有办法匹配(一辈子单身,惨)了……
咳咳咳,通过黑色和白色字的讲解,可以大致了解匈牙利算法了。那么来看看这道题吧。
我们可以显而易见的看出,按国际象棋格子的分法,有黑色和白色之分,可以很容易的发现,马从黑色只能跳到白色,白色只能跳到黑色,也就是处于白色格子的没有自区域的相连,黑的同样没有,符合二分图的性质,而一步可以跳到的地方就相当于有一条边相连。
有边相连的格点不可以同时放马,所以放了一个马与之相连的所有边就全部被控制。删去最少点使得所有边都不会冲突,这就是最小点覆盖边问题!答案是等于最大匹配的!然后用总数减去最大匹配数即可了!
当然,有了思路,要想不超时,就看你的代码丑不丑了……
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int getint(){int p=0,f=0;char c=getchar();while((c<'0'||c>'9')&&c!='-')c=getchar();if(c=='-')f=1,c=getchar();while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();return f?-p:p;}void putint(int p){if(p<0)putchar('-'),p=-p;if(p>9)putint(p/10);putchar(p%10+'0');}int n,m,sum,cnt[2];bool A[205][205];int num[205][205];int d[8][2]={{2,1},{-2,1},{2,-1},{-2,-1},{1,2},{-1,2},{1,-2},{-1,-2}};int to[20005][10];int CP[20005];bool vis[20005];bool check(int x,int y){if(x<1||y<1||x>n||y>n||A[x][y]||vis[num[x][y]])return 0;return 1;}bool xyl(int x){for(int i=1;i<=to[x][0];i++){int p=to[x][i];if(!vis[p]){vis[p]=1;if(!CP[p]||xyl(CP[p])){CP[p]=x;return 1;}}}return 0;}int main(){n=getint();m=getint();for(int i=1;i<=m;i++){int a=getint(),b=getint();A[a][b]=1;}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(!A[i][j])num[i][j]=++cnt[(i+j)%2];for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(!A[i][j]&&(i+j)%2==0)for(int k=0;k<8;k++)if(check(i+d[k][0],j+d[k][1]))to[num[i][j]][++to[num[i][j]][0]]=num[i+d[k][0]][j+d[k][1]];for(int i=1;i<=cnt[0];i++){sum+=xyl(i);memset(vis,0,sizeof(vis));}putint(cnt[1]+cnt[0]-sum);}
- 【学校OJ】二分图匹配 骑士共存问题
- 骑士共存问题 (二分图最大匹配 转换 网络最大流 )
- Codevs_P1922 骑士共存问题(Dinic算法最大流+二分图匹配)
- 骑士共存问题 二分图的最大独立集
- codevs 1922 骑士共存问题||二分图||最大独立集||二分图匹配||Dinic与匈牙利算法的讨论||网络流
- [网络流24题][codevs1922] 骑士共存问题 二分图最大独立集
- [网络流24题]骑士共存问题 二分图/最大点权独立集
- 骑士共存问题
- 线性规划与网络流24题の24 骑士共存问题 (二分图最大独立集)
- 【网络流24题】骑士共存问题(二分图染色+最大权独立子集+最小割)
- loj6226「网络流 24 题」骑士共存问题(二分图最大点独立集,最小割)
- [codevs 1922] 骑士共存问题
- 洛谷 P3355 骑士共存问题
- 洛谷3355 骑士共存问题
- 【网络流二十四题 骑士共存问题】【二分图点权最大独立集->最小割】
- [网络流24题] 24 骑士共存(二分图最大独立集,网络最小割)
- code vs 1922 骑士共存问题
- 骑士共存问题(最大流)
- less学习笔记
- robotium真机调试出现Installation failed due to invalid APK file!错误的解决办法
- RabbitMQ和kafka从几个角度简单的对比
- Spring整合Mybatis
- ASN.1探索 - 2 基础知识(1)
- 【学校OJ】二分图匹配 骑士共存问题
- 过了太久我已经不记得这个是啥玩意了,隐约觉得第二第三题方法都太笨了
- C语言基础练习题c语言试题100道(前三十道)
- 数据库关键字
- Angular4学习笔记(四):service
- 菜鸟始终不明白互斥对象和 WaitForSingleObject!
- hud 2084
- 1204: 杨八方的数学问题 [数学]
- json字符串转数组、对象(json_decode)