poj 3692二分图……本人太弱,才明白过来。
来源:互联网 发布:人工智能贴吧 编辑:程序博客网 时间:2024/06/06 20:08
首先说明一下,由两个完全子图连接而成的图的补图一定是二分图。
然后是这个题了。
本来想直接用二分,结果一看不对啊,匈牙利算法并不符合题意啊。
那怎么办……
方法:
题意给的图是两个完全子图连接而成的图,
那么我们先取它的补图。补图上凡是两点之间有边的,都是原图上相互间没有关系的(对应于题意就是两个人不认识的)。
那么我们选点(也就是选人)就不能选在相同边上的两个点,对吧?(因为他们不认识啊。)
又一想,这不是点独立集吗?就是求原图的补图的最大点独立集就是了。
那怎么求?有定理可以用:最大点独立集点数+最大匹配数=总顶点数。
然后就可以AC啦~
这边我用的是很基础的dfs匈牙利~
AC代码:
注意Boy和Girl是有顺序的,for循环别弄反了。
#include <iostream>#include <string>#include <cstring>#include <cstdio>using namespace std;const int maxn=4e3+10;int B,G,M;bool mp[maxn][maxn];bool used[maxn];int mate[maxn];bool Findm(int x){ for(int i=1;i<=B;i++) { if(!used[i]&&mp[x][i]) { used[i]=1; if(!mate[i]||Findm(mate[i])) { mate[i]=x; return 1; } } } return 0;}int main(){ int cas=1; while(scanf("%d%d%d",&G,&B,&M)==3&&B&&G&&M) { for(int i=1;i<=maxn;i++)//本来是初始化为0的,现在都初始化为1 for(int j=1;j<=maxn;j++) mp[i][j]=1; for(int i=1;i<=M;i++) { int t1,t2; scanf("%d%d",&t1,&t2); mp[t1][t2]=0;//逆着建图就好了。 } int temp=0; memset(mate,0,sizeof(mate)); for(int i=1;i<=G;i++)//题目描述的是哪个Girl认识哪个Boy而不是Boy认识Girl,所以for循环别反了,WA了几发…… { memset(used,0,sizeof(used)); temp+=Findm(i); } printf("Case %d: %d\n",cas++,B+G-temp); }}
阅读全文
0 0
- poj 3692二分图……本人太弱,才明白过来。
- 上了大学才明白的事……
- 程序员30岁以后才明白……
- 程序员30岁以后才明白……
- 程序员30岁以后才明白……
- Android dump .so 文件crash log(不太明白 转载过来以便需要的时候使用)
- 到现在才明白
- 回家后才明白
- 三十以后才明白
- 现在才明白
- 现在才明白
- 人到中年才明白
- RECT 没太明白
- 不太明白
- 见过这些图 才明白什么叫坐井观天!
- poj 3692 二分图匹配
- POJ 2446 Chessboard 二分匹配,藏得太深了
- 人生太晚,明白太晚
- Python标准异常总结
- CodeForces
- 什么是B+Tree
- 循环结构中break、continue、return和exit的区别
- jdk8源码解析系列--前言
- poj 3692二分图……本人太弱,才明白过来。
- POJ 1321 Chess Problem 基础DFS
- 基本数据类型 、包装类 与String类之间的转换
- hdu 1232 畅通工程 (并查集)
- 设计原则笔记
- Triangle问题及解法
- 修改Android内核配置
- Python简介
- Java用同步代码块实现线程同步