您的位置:首页 > 其它

HDU 3081 Marriage Match Il【并查集 + 二分匹配】

2012-10-11 20:37 543 查看
题意: 有 2*n个同学,n男n女,知道了 有 m 对 男女之间木有吵过架,现在这 n 个女生要找对象,要求没有和她吵过架或者没有和她的一个朋友吵过架,

当 n 个女生都找到对象的时候算作一轮,然后重新找,满足每个女生都不能找和上次一样的对象,问最多能进行多少轮。

分析: 将是朋友关系的女生放到一个集合,用来降低建图的时间复杂度。

#include <stdio.h>
#include <string.h>
#define maxn 102
#define clr(x)memset(x,0,sizeof(x))
int f[maxn];
int search(int x)
{
return f[x] == x?x:(f[x] = search(f[x]));
}
void join(int x,int y)
{
int fx = search(x);
int fy = search(y);
if(fx != fy){
if(fx < fy)
f[fy] = fx;
else f[fx] = fy;
}
}
int link[maxn];
int v[maxn];
int g[maxn][maxn];
int tt[maxn][maxn];
int n;
int find(int x)
{
int i;
for(i = 1; i <= n; i++){
if(g[x][i]&&!v[i]){
v[i] = 1;
if(link[i] == 0||find(link[i])){
link[i] = x;
return 1;
}
}
}
return 0;
}
struct noql
{
int girl,boy;
}r[maxn*maxn];
int main()
{
int t;
int m, F;
int i, j;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&n, &m, &F);
for(i = 1; i <= n; i++)
f[i] = i;
clr(g);
int a,b;
for(i = 1; i <= m; i++)
scanf("%d %d",&r[i].girl, &r[i].boy);
while(F--){
scanf("%d %d",&a, &b);
join(a,b);
}
for(i = 1; i <= m; i++)
g[search(r[i].girl)][r[i].boy] =  1;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
if(g[search(i)][j] == 1)
g[i][j] = 1;
int res = 0;
while(1){
clr(link);
for(i = 1; i <= n; i++){
clr(v);
if(!find(i))
break;
}
if(i != n+1)
break;
res++;
for(i = 1; i <= n; i++)
g[link[i]][i] = 0;
}
printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: