hdu3081 Marriage Match II

来源:互联网 发布:淘宝商品详情图做法 编辑:程序博客网 时间:2024/05/20 02:21

题目大意就是有n对男女,玩儿结婚游戏,要求就是开始每个女生心目中都会有几个心仪的男生,同时呢,好友(girl)心仪的男生也是可以选做自己的boyfriend。每一轮游戏男女配对(只和心仪的)且不于之前配对过的配对,问最多可以玩儿几轮这样的游戏。

男女配对显然是二分图,然后就是二分次数k,k必然是大于1而小于n+1的。

/*****************************************Author      :Crazy_AC(JamesQi)Time        :2015File Name   :*****************************************/// #pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <algorithm>#include <iomanip>#include <sstream>#include <string>#include <stack>#include <queue>#include <deque>#include <vector>#include <map>#include <set>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <climits>using namespace std;#define MEM(x,y) memset(x, y,sizeof x)#define pk push_backtypedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> ii;typedef pair<ii,int> iii;const double eps = 1e-10;const int inf = 1 << 30;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;const int N = 110;int g[N][N];int n, m, f;int F[N];int Find(int x) {return F[x] == -1?x:F[x] = Find(F[x]);}void input() {memset(g, 0,sizeof g);scanf("%d%d%d",&n,&m,&f);int u, v;for (int i = 1;i <= m;++i) {scanf("%d%d",&u,&v);g[u][v] = 1;}memset(F, -1,sizeof F);for (int i = 1;i <= f;++i) {scanf("%d%d",&u,&v);int t1 = Find(u),t2 = Find(v);if (t1 != t2) F[t1] = t2;}for (int i = 1;i <= n;++i) {for (int j = 1;j <= n;++j) {int t1 = Find(i),t2 = Find(j);if (t1 == t2) {for (int k = 1;k <= n;++k)g[i][k] |= g[j][k];}}}}int head[N*3], pnt[N*1000], nxt[N*1000], cap[N*1000], flow[N*1000];int cnt;int cur[N*3];int dis[N*3];void addedge(int u,int v,int can) {pnt[cnt] = v,cap[cnt] = can, flow[cnt] = 0;nxt[cnt] = head[u], head[u] = cnt++;pnt[cnt] = u,cap[cnt] = 0,flow[cnt] = 0;nxt[cnt] = head[v], head[v] = cnt++;}bool bfs(int s,int t) {queue<int> que;que.push(s);memset(dis, -1,sizeof dis);dis[s] = 0;while(!que.empty()) {int u = que.front();que.pop();for (int i = head[u];i!=-1;i = nxt[i]) {if (dis[pnt[i]] == -1 && cap[i] > flow[i]) {dis[pnt[i]] = dis[u] + 1;que.push(pnt[i]);}}}return dis[t] != -1;}int dfs(int u,int a,int t) {if (u == t || a == 0) return a;int sum = 0;for (int &i = cur[u];~i;i = nxt[i]) {int v = pnt[i];int f;if (dis[v] == dis[u] + 1 && (f = dfs(v, min(a, cap[i] - flow[i]), t)) > 0) {sum += f;flow[i] += f;flow[i^1] -= f;a -= f;if (a == 0) break;}}return sum;}int MaxFlow(int s,int t) {int sum = 0;while(bfs(s, t)) {memcpy(cur, head, sizeof head);sum += dfs(s, INF, t);}return sum;}void getmap(int mid) {memset(head, -1,sizeof head);cnt = 0;int s = 0, t = n*2+1;for (int i = 1;i <= n;++i) {addedge(s, i, mid);addedge(i + n, t, mid);for (int j = 1;j <= n;++j) {if (g[i][j]) addedge(i, j+n, 1);}}}int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);int t;scanf("%d",&t);while(t--) {input();int low = 1,high = n + 1;int ans = -1;while(low < high) {int mid = (low + high) / 2;getmap(mid);int tmp = MaxFlow(0,n*2+1);if (tmp == n*mid) {low = mid + 1;}else high = mid;}printf("%d\n", low - 1);}return 0;}


0 0