【hdu2444】The Accomodation of Students【二分图匹配】

在这里插入图片描述

分析

把关系看成一个图,就可以发现如果能分好组那就具有二分图特征。

所以题目分成两步,判断是否是二分图,求出最大匹配。

第一步就DFS黑白染色,如果有矛盾就不是二分图。

第二步匈牙利算法一个个分配室友,一些实现细节要注意,比如求最大匹配的时候要手动变成单向边(只能从黑指向白)。

上代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int n,m,col;
int g[210][210],v[210];
int color[210],link[210],cover[210];

bool dfs(int x,int fx,int col)
{
	v[x]=1;color[x]=col;
	for(int i=1;i<=n;i++)
	{
		if(!g[x][i]||i==fx) continue; 
		if(v[i]&&color[i]==col) return false;
		if(!v[i]&&!dfs(i,x,1-col)) return false;
	}
	return true;
}

bool find(int x)
{
	for(int i=1;i<=n;i++)
	{
		if(!g[x][i]||color[i]==1) continue;
		if(!cover[i])
		{
			cover[i]=1;
			int t=link[i];
			link[i]=x;
			if(t==0||find(t))
			{
				return true;
			}
			link[i]=t;
		}
	}
	return false;
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(v,0,sizeof(v));
		memset(g,0,sizeof(g));
		memset(link,0,sizeof(link));
		memset(color,0,sizeof(color));
		for(int i=1;i<=m;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			g[x][y]=g[y][x]=1;
		}
		bool kk=1;
		for(int i=1;i<=n;i++)
		{
			if(!v[i]) kk&=dfs(i,0,0);
		}
		if(!kk)
		{
			cout<<"No"<<endl;
			continue;
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			memset(cover,0,sizeof(cover));
			if(link[i]==0&&find(i)) ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值