您的位置:首页 > 其它

POJ 2289 Jamie’s Contact Groups-二分匹配&多重匹配

2016-08-02 23:11 507 查看
思路:二分匹配的多重匹配,和普通的匹配在于每个右侧集合的点可以匹配多个左侧集合的点,对于寻找增广路首先判断一个点是否匹配够上限,然后若够上限了,再枚举是否有增广路,然后此题就是二分出一个上限,然后判断二分图是否可以在这个上限内完全匹配,若可以则向左二分。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int maxn = 1500;
int e[maxn][maxn],book[maxn];
int n,m;
struct node
{
int l,s[1001];
}a[maxn];
int dfs(int x,int mid)
{
int i,j;
for(i=1;i<=m;i++)
{
if(e[x][i] && !book[i])
{
book[i] = 1;
if(a[i].l < mid)
{
a[i].s[a[i].l++] = x;
return 0;
}
for(j=0;j<a[i].l;j++)
{
if(!dfs(a[i].s[j],mid))
{
a[i].s[j] = x;
return 0;
}
}
}
}
return 1;
}
int f(int x)
{
int ans = 0,i;
for(i=1;i<=m;i++)
a[i].l = 0;
for(i=1;i<=n;i++)
{
memset(book,0,sizeof(book));
if(dfs(i,x))
return 0;
}
return 1;
}
int main(void)
{
int i,j,x;
char c[100],ch;
while(scanf("%d%d",&n,&m)==2)
{
if(!n && !m)
break;
memset(e,0,sizeof(e));
for(i=0;i<n;i++)
{
scanf("%s",c);
while(scanf("%d%c",&x,&ch))
{
e[i+1][x+1] = 1;
if(ch == '\n')
break;
}
}
int l = 0,r = n,ans = n;
while(l<=r)
{
int mid = (l+r)>>1;
if(f(mid))
{
ans = mid;
r = mid - 1;
}
else
l = mid + 1;
}
cout << ans << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: