HDU 2444 The Accomodation of Students(二分图判定+最大匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=2444
题意:
给你N个学生与M对关系,每个关系形如(i,j),表示第i个学生与第j个学生相互认识. 现在要你将N个学生分成两组,每组中的任意两个学生都不相互认识.
如果N个学生能分组的话,那么就将这N个学生放到尽量多的双人房中去.每个房间放2个相互认识的人.问你最多需要多少房间?
分析:
首先第一步将N个学生分成两类就是看能否将图二分.假设每个学生是一个节点,如果i学生与j学生认识,那么i点和j点之间连一条无向边. 然后我们将图分成两部分,左边部分和右边部分.且各部分内部不存在边,所有边一定是左边与右边点之间的边.(这就是二分图的定义)
判断二分图的话直接用刘汝佳的模板即可.
如果该图能二分, 直观的做法是将所有点重新编号分成左右两边.然后再计算最大匹配. 但是给点重新编号明显比较麻烦,这里我们将原图翻倍处理,然后直接计算出翻倍后图的最大匹配数X. 最终X/2就是我们所求.
翻倍原图具体原理证明在POJ1466:
http://blog.csdn.net/u013480600/article/details/38638219
AC代码:
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 200+10;
struct Max_Match
{
int n;
int color[maxn];//颜色数组,用于二分图判定
vector<int> g[maxn];
bool vis[maxn];
int left[maxn];
void init(int n)
{
this->n=n;
for(int i=1;i<=n;i++) g[i].clear();
memset(left,-1,sizeof(left));
}
bool bipartite(int u)
{
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(color[v] == color[u]) return false;
else if(color[v]==0)
{
color[v]= 3-color[u];
if(!bipartite(v)) return false;
}
}
return true;
}
bool match(int u)
{
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v])
{
vis[v]=true;
if(left[v]==-1 || match(left[v]))
{
left[v]=u;
return true;
}
}
}
return false;
}
int solve()
{
memset(color,0,sizeof(color));
for(int i=1;i<=n;i++)if(!color[i])//因为该图不一定连通,所以需要所有点做起点判断一遍
{
color[i]=1;
if(!bipartite(i)) return -1;
}
int ans=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(match(i)) ans++;
}
return ans;
}
}MM;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==2)
{
MM.init(n);
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
MM.g[u].push_back(v);//判断2分图,由于是无向的,所以需要添加两次边
MM.g[v].push_back(u);//计算原图翻倍的最大匹配,也需要添加两次边
}
int ans=MM.solve();
if(ans==-1) printf("No\n");
else printf("%d\n",ans/2);
}
return 0;
}
分享到:
相关推荐
本人准备2020年保研机试时刷的题目(虽然最后机试取消了,...来自某中流985,在HDU和vjudge平台上大概刷了400道。本文件地图(excel表格)包含了绝大部分我刷过的题目,笔记中具有思路、代码、总结和心得。 大佬勿入!
二分图匹配实例代码及整理 1、匈牙利算法 HDU 1150 #include #include #include using namespace std; int m,n,k; int vis[105]; int mpt[105][105]; int use[105]; int hungary(int x) { for(int i=1;i<m;i++)...
B HDU 5093 Battle ships题意给出一个n行m列的图,*代表海域,o代表冰水,#代表冰山,要想在海域中放置船,保证船与船之间不能相互看到,之间
The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set. For example, the LCM of 5, 7 and 15 is 105. Input Input...
hdu 1695 GCD(欧拉函数+容斥原理).docx
杭电ACM课件2014版之(HDUACM2010版_13)二分匹配及其应用
HDU二分匹配及其应用,此PPT是刘春英老师版权所有, 特此贡献给广大编程爱好者,特别是对于ACMer
HDU的1250,主要是利用高精度加法,但是代码有点繁琐,效率不是很高
The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases. In each test case, there are two integers k,m(1≤k≤1018,1≤m≤100). Output For each test case, print ...
ACM题库,一些题目和答案,以及解题报告,传上来共享
杭电ACMhdu1163
HDU1059的代码
hdu1001解题报告
300+ AC 代码 。 大数 , 线段树 , 字符串 , dp.....
hdu 1574 passed sorce
HDU的一题........HDU DP动态规
acm hdu as easy as a+b
hdu acm 教案 搜索入门 hdu acm 教案 搜索入门
hdu2101AC代码
搜索 dfs 解题代码 hdu1241