题解:poj3715 Blue and Red 【二分图】

传送门

这个题目就是二分图最大匹配,然后输出字典序最小的那个编号,这个输出和[NOI2009]变换序列有点像,区别就是这个题水一些

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; 
const int M  =  210;
bool g[M][M],vis[M],del[M],book[M];
int px[M],py[M];
int n;
bool Hun(int x) {
	if(del[x]) return 0;
	for(int i=0;i<n;i++) {
		if(!g[x][i]||vis[i]||del[i]||!book[i]) continue;
		vis[i] = 1;
		if(py[i]==-1||Hun(py[i])) {
			px[x]=i; 
			py[i]=x;
			return 1;
		}
	}
	return 0;
}
bool hun(int y) {
	if(del[y]) return 0;
	for(int i=0;i<n;i++) {
		if(!g[y][i]||vis[i]||del[i]||book[i]) continue;
		vis[i] = 1;
		if(px[i]==-1||hun(px[i])) {
			px[i]=y;
			py[y]=i;
			return 1;
		}
	}
	return 0;
}
int main()
{
	int t;
	cin>>t;
	while(t--) {
		int m;
		scanf("%d%d",&n,&m);
		memset(g,0,sizeof(g));
		memset(del,0,sizeof(del));
		memset(px,-1,sizeof(px));
		memset(py,-1,sizeof(py));
		for(int i=0;i<n;i++) cin>>book[i];
		for(int i=0;i<m;i++) {
			int j,k;
			cin>>j>>k;
			if(book[j]!=book[k])
				g[j][k]=g[k][j]=1;
		}
		int ans=0;
		for(int i=0;i<n;i++) 
			if(book[i]==0) {
				memset(vis,0,sizeof(vis));
				ans+=Hun(i);
			}
		cout<<ans<<" ";
		int x,y;
		for(int i=0;i<n&&ans;i++) {
			if(!book[i]) {
				if(px[i]==-1 ) continue;
				y=px[i];
				del[i]=1;
				px[i]=-1;
				py[y]=-1;
				memset(vis,0,sizeof(vis));
				if(hun(y))
					del[i] = 0;
				cout<<i<<" ";
			}
			else 
			{
				if(py[i] == -1) continue;
				x = py[i];
				del[i] = 1;
				py[i] = -1;
				px[x] = -1;
				memset(vis,0,sizeof(vis));
				if(Hun(x))
					del[i] = 0;
				cout<<i<<" ";
			}
		}
		cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值