B - The Accomodation of Students(二分图判断&匹配)

B - The Accomodation of Students(二分图判断&匹配)

题意:给定若干条有向边,判断该图是否为二分图,并且求最大二分匹配。

思路:用染色法判断二分图+匈牙利算法解决。
时间复杂度: O ( n 3 + n 2 ) O(n^3+n^2)

AC代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=2e2+10;
bool g[N][N];
int n,m,vis[N],mh[N],col[N];
void init(int n){ //初始化 
	for(int i=1;i<=n;i++)
		vis[i]=mh[i]=col[i]=0;
		memset(g,0,sizeof g);
}
int bfs(){ //染色法判断二分图 
	queue<int>q;
	q.push(1);
	col[1]=1;
	while(q.size()){
		int u=q.front();q.pop();
		 for(int v=1;v<=n;v++)
		 	if(g[u][v]){
		 		if(!col[v]) col[v]=-col[u],q.push(v);//放到对立集. 
		 		else if(col[u]==col[v]) return 0;
			 }		
		}
	return 1;
}
int find(int u){ //找妹子. 
	for(int i=1;i<=n;i++){
		if(g[u][i]&&!vis[i]){
			vis[i]=1;
			if(!mh[i]||find(mh[i]))
			{
				mh[i]=u;
				return 1;
			}
		}
	}
	return 0;
}
int fun(){ //计算答案. 
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		ans+=find(i);
	 }
	 return ans; 
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		init(n);
		for(int i=1,u,v;i<=m;i++){
			scanf("%d%d",&u,&v);
			g[u][v]=1;
		}
		if(!bfs()) puts("No");
		else printf("%d\n",fun());
	}
	return 0;
}
原创文章 201 获赞 165 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/105929297