HDU 3605 二分图的多重匹配 || 状压网络流

九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/12843889

题意:

n个人m个星球,下面 n*m 的矩阵

i行第j个  为1 表示 第i人能住在j星球  为0表示不能居住

 

最后一行m个表示该星球容量

问是不是所有人都能住在m个星球里

 

 思路:

这个题最大流比较好想

 

二分图建图:

n个人建x集 , 矩阵直接做映射边,   m个星球因为非单一匹配,所以用栈

 

这里需要一个优化就是,如果第i人不能居住了 , 直接跳出匹配算法,输出NO

 

或者用状压+网络流:

因为m<=10,所以每个人的选择情况只有2^m种,把选择相同的人状压归类,这样人的点可以变为1024个点

 

#include<stdio.h>
#include<string.h>

#define M 11
#define N 100001
#define stack Stack

int n,m;

int stack[M][N], top[M], Maxpeo[M];
int map[N][M];
bool T[M];
int dfs(int u){
	for(int i = 1; i <= m; i ++)
		if(map[u][i] && !T[i])
		{

			T[i] = true;

			if(top[i]<Maxpeo[i])
			{
				stack[i][top[i] ++ ] = u;
				return 1;
			}
			for(int j = 0; j<top[i] ;j++)
				if( dfs(stack[i][j]) )
				{
					stack[i][j] = u;
					return 1;
				}

		}
		return 0;
}
bool solve(){
	memset(top, 0, sizeof(top));

	for(int i = 1; i <= n; i++)
	{
		memset(T, 0, sizeof(T));
		if(!dfs(i)) return false;
	}

	return true;
}
void Input(){
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			scanf("%d",&map[i][j]);

	for(int i = 1; i <= m; i++)scanf("%d",&Maxpeo[i]);
}
int main(){

	while(~scanf("%d %d",&n,&m)){
		Input();

		if(solve())printf("YES\n");
		else	   printf("NO\n");
	}
	return 0;
}

/*
1 1
1
1

2 2
1 0
1 0
1 1

ans:
YES
NO

*/


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值