标签: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