poj 3343 Against Mammoths 二分图最大匹配

题意:

人类有H颗星球,外新人有A颗星球,1颗人类星球只能攻占1颗外星人星球,1颗外星人星球也只能被1颗人类星球攻占。人类星球h在满足如下条件可以攻占外星人星球a:

人类舰队从h星球经一定时间到a星球时人类舰队飞船数量大于等于外星人舰队飞船数量。求人类攻占所有外星人星球的最短时间。

思路:

二分时间t,对每个t,求二分图最大匹配看在t时间内是否攻占所有外星人星球。

代码:

//poj 3343
//sepNINE
#include<iostream>
using namespace std;
const int maxN=256; 

int M,v1,v2,t,H,A;
bool vis[maxN];
int link[maxN];
bool g[maxN][maxN];
int n[maxN],m[maxN],a[maxN],b[maxN];
int mat[maxN][maxN];

bool dfs(int x)
{
	for(int y=1;y<=v2;++y)	
		if(g[x][y]&&!vis[y]){
			vis[y]=true;
			if(link[y]==0||dfs(link[y])){
				link[y]=x;
				return true;
			}
		}
	return false;
}

void hungary()
{
	for(int x=1;x<=v1;++x){
		memset(vis,false,sizeof(vis));
		if(dfs(x))
			++M;
	}	
	return ;
}

bool win()
{
	int i,j;
	memset(link,0,sizeof(link));
	memset(g,false,sizeof(g));
	for(i=1;i<=H;++i)
		for(j=1;j<=A;++j)
			if(mat[i][j]<=t&&n[i]+1LL*m[i]*(t-mat[i][j])>=a[j]+1LL*t*b[j])
					g[i][j]=1;
			
	M=0;
	v1=H;
	v2=A;
	hungary();
	if(M==A)
		return true;
	return false;
			
}

int main()
{

	while(scanf("%d%d",&H,&A)==2&&H){
		int i,j;
		for(i=1;i<=H;++i)
			scanf("%d%d",&n[i],&m[i]);
		for(i=1;i<=A;++i)
			scanf("%d%d",&a[i],&b[i]);					
		for(i=1;i<=H;++i)
			for(j=1;j<=A;++j)
				scanf("%d",&mat[i][j]);
		int low=0,high=INT_MAX;
		while(low<high){
			//t=(low+high)/2;
			t=low/2+high/2;
			if(low%2==1&&high%2==1) ++t;
			if(win())
				high=t;	
			else
				low=t+1;	
		}
		if(low==INT_MAX)
			printf("IMPOSSIBLE\n");
		else
			printf("%d\n",low);
	} 
	return 0;	
}
 
 
 



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值