标签:marriage match ii hdu 3081 二分图+并查集
1 4 5 2 1 1 2 3 3 2 4 2 4 4 1 4 2 3
2
题意:n个女孩n个男孩,女孩选男朋友,如果两个女孩认识,那她们可以在自己认识的或对方认识的男孩中任选一个,选完一轮后打乱重新选,已经配对过的不能再选在一起,问最后最多能选几轮。
思路:先用并查集,再建图进行二分匹配,一次匹配完后将匹配的边去掉再进行匹配,直到匹配数<n。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 105
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std;
int n,m,f;
int g[maxn][maxn];
int linker[maxn];
bool used[maxn];
int father[maxn];
void init()
{
memset(g,0,sizeof(g));
for (int i=0;i<maxn;i++)
father[i]=i;
}
int find_father(int x)
{
if (x!=father[x])
father[x]=find_father(father[x]);
return father[x];
}
void Union(int a,int b)
{
int fa=find_father(a);
int fb=find_father(b);
if (fa!=fb)
father[fa]=fb;
}
bool dfs(int u)
{
for (int v=1;v<=n;v++)
{
if (g[u][v]&&!used[v])
{
used[v]=true;
if (linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int solve()
{
int ans=0;
while (1)
{
int res=0;
memset(linker,-1,sizeof(linker));
for (int u=1;u<=n;u++)
{
memset(used,false,sizeof(used));
if (dfs(u)) res++;
}
// printf("res=%d\n",res);
if (res<n) break;
for (int i=1;i<=n;i++)
g[linker[i]][i]=0;
ans++;
}
return ans;
}
int main()
{
int i,j,t,a,b,k;
scanf("%d",&t);
while (t--)
{
init();
scanf("%d%d%d",&n,&m,&f);
for (i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
g[a][b]=1;
}
for (i=0;i<f;i++)
{
scanf("%d%d",&a,&b);
Union(a,b);
}
for (i=1;i<=n;i++)
{
int x=find_father(i);
for (j=1;j<=n;j++)
{
if (j!=i&&find_father(j)==x)
{
for (k=1;k<=n;k++)
{
if (g[j][k])
g[i][k]=1;
}
}
}
}
printf("%d\n",solve());
}
return 0;
}
Marriage Match II (hdu 3081 二分图+并查集)
标签:marriage match ii hdu 3081 二分图+并查集
原文地址:http://blog.csdn.net/u014422052/article/details/45201111