HDU 3081 Marriage Match II

pid=3081" target="_blank" style="">题目链接

题意:n个女孩n个男孩,每一个女孩能够和一些男孩配对。然后有些女孩是朋友。满足这个朋友圈里面的人,假设有一个能和某个男孩配对,其它就都能够,然后每轮要求每一个女孩匹配到一个男孩。且每轮匹配到的都不同,问最多能匹配几轮

思路:二分轮数k,然后建图为,源点连向女孩,男孩连向汇点容量都为k,然后女孩和男孩之间连边为。有关系的连边容量1,这样一个匹配相应一条边。且不会反复,每次推断最大流是否等于n * k就可以

代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std; const int MAXNODE = 205;
const int MAXEDGE = 100005; typedef int Type;
const Type INF = 0x3f3f3f3f; struct Edge {
int u, v;
Type cap, flow;
Edge() {}
Edge(int u, int v, Type cap, Type flow) {
this->u = u;
this->v = v;
this->cap = cap;
this->flow = flow;
}
}; struct Dinic {
int n, m, s, t;
Edge edges[MAXEDGE];
int first[MAXNODE];
int next[MAXEDGE];
bool vis[MAXNODE];
Type d[MAXNODE];
int cur[MAXNODE];
vector<int> cut; void init(int n) {
this->n = n;
memset(first, -1, sizeof(first));
m = 0;
}
void add_Edge(int u, int v, Type cap) {
edges[m] = Edge(u, v, cap, 0);
next[m] = first[u];
first[u] = m++;
edges[m] = Edge(v, u, 0, 0);
next[m] = first[v];
first[v] = m++;
} bool bfs() {
memset(vis, false, sizeof(vis));
queue<int> Q;
Q.push(s);
d[s] = 0;
vis[s] = true;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int i = first[u]; i != -1; i = next[i]) {
Edge& e = edges[i];
if (!vis[e.v] && e.cap > e.flow) {
vis[e.v] = true;
d[e.v] = d[u] + 1;
Q.push(e.v);
}
}
}
return vis[t];
} Type dfs(int u, Type a) {
if (u == t || a == 0) return a;
Type flow = 0, f;
for (int &i = cur[u]; i != -1; i = next[i]) {
Edge& e = edges[i];
if (d[u] + 1 == d[e.v] && (f = dfs(e.v, min(a, e.cap - e.flow))) > 0) {
e.flow += f;
edges[i^1].flow -= f;
flow += f;
a -= f;
if (a == 0) break;
}
}
return flow;
} Type Maxflow(int s, int t) {
this->s = s; this->t = t;
Type flow = 0;
while (bfs()) {
for (int i = 0; i < n; i++)
cur[i] = first[i];
flow += dfs(s, INF);
}
return flow;
} void MinCut() {
cut.clear();
for (int i = 0; i < m; i += 2) {
if (vis[edges[i].u] && !vis[edges[i].v])
cut.push_back(i);
}
}
} gao; const int N = 105; int t, n, m, f, g[N][N], parent[N]; int find(int x) {
return x == parent[x] ? x : parent[x] = find(parent[x]);
} bool judge(int k) {
int s = 0, t = n * 2 + 1;
gao.init(t + 1);
for (int i = 1; i <= n; i++) {
gao.add_Edge(s, i, k);
gao.add_Edge(i + n, t, k);
for (int j = 1; j <= n; j++)
if (g[i][j]) gao.add_Edge(i, j + n, 1);
}
return gao.Maxflow(s, t) == n * k;
} int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d%d", &n, &m, &f);
memset(g, 0, sizeof(g));
for (int i = 1; i <= n; i++) parent[i] = i;
int u, v;
while (m--) {
scanf("%d%d", &u, &v);
g[u][v] = 1;
}
while (f--) {
scanf("%d%d", &u, &v);
int pa = find(u);
int pb = find(v);
if (pa != pb) parent[pa] = pb;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
if (find(i) == find(j)) {
for (int k = 1; k <= n; k++)
g[i][k] |= g[j][k];
}
}
int l = 1, r = n + 1;
while (l < r) {
int mid = (l + r) / 2;
if (judge(mid)) l = mid + 1;
else r = mid;
}
printf("%d\n", l - 1);
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

HDU 3081 Marriage Match II(二分法+最大流量)的更多相关文章

  1. HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)

    HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...

  2. HDU 3081 Marriage Match II (二分图,并查集)

    HDU 3081 Marriage Match II (二分图,并查集) Description Presumably, you all have known the question of stab ...

  3. HDU 3081 Marriage Match II 二分 + 网络流

    Marriage Match II 题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女 ...

  4. HDU 3081 Marriage Match II 最大流OR二分匹配

    Marriage Match IIHDU - 3081 题目大意:每个女孩子可以和没有与她或者是她的朋友有过争吵的男孩子交男朋友,现在玩一个游戏,每一轮每个女孩子都要交一个新的男朋友,问最多可以玩多少 ...

  5. HDU - 3081 Marriage Match II 【二分匹配】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意 有n对男女 女生去选男朋友 如果女生从来没和那个男生吵架 那么那个男生就可以当她男朋友 女 ...

  6. HDU 3081 Marriage Match II

    二分图的最大匹配+并查集 每次匹配完之后,删除当前匹配到的边. #include<cstdio> #include<cstring> #include<cmath> ...

  7. HDU 3081 Marriage Match II (二分+并查集+最大流)

    题意:N个boy和N个girl,每个女孩可以和与自己交友集合中的男生配对子;如果两个女孩是朋友,则她们可以和对方交友集合中的男生配对子;如果女生a和女生b是朋友,b和c是朋友,则a和c也是朋友.每一轮 ...

  8. HDU 3081 Marriage Match II (二分+网络流+并查集)

    注意 这题需要注意的有几点. 首先板子要快,尽量使用带当前弧优化的dinic,这样跑起来不会超时. 使用弧优化的时候,如果源点设置成0,记得将cur数组从0开始更新,因为有的板子并不是. 其次这题是多 ...

  9. hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //灵活运用最大流量

    3081 意甲冠军: n女生选择不吵架,他甚至男孩边(他的朋友也算.并为您收集过程).2二分图,一些副作用,有几个追求完美搭配(每场比赛没有重复的每一个点的比赛) 后.每次增广一单位,(一次完美匹配) ...

随机推荐

  1. Windows Phone开发(46):与Socket有个约会

    原文:Windows Phone开发(46):与Socket有个约会 不知道大家有没有"谈Socket色变"的经历?就像我一位朋友所说的,Socket这家伙啊,不得已而用之.哈,S ...

  2. Android 动态显示和隐藏软键盘

    ** * 动态设置软盘的显示和隐藏 * @author JPH */ public class MainActivity extends Activity implements OnClickList ...

  3. JS获得URL参数

    使用JavaScript获得URL在参数值 方法一: function getUrlParam(name) {      var reg = new RegExp("(^|&)&qu ...

  4. Android在发送带有附件的邮件

    准备好工作了-下载最新的版本号JMail https://java.net/projects/javamail/pages/Home#Download_JavaMail_1.5.2_Release h ...

  5. Android 4.0新组件:GridLayout详细说明

    于Android 4.0(API 14)它提供了一个新的组件GridLayout,它继承自Linearlayout,用于执行网络格样式布局. 在某些方面,GridLayout与TableLayout和 ...

  6. wcf例子01

    一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...

  7. Blend4精选案例图解教程(四):请给我路径指引

    原文:Blend4精选案例图解教程(四):请给我路径指引 路径在界面设计中,可以起到很好的辅助作用,我常常使用它来对元素进行规则排列和非规则排列控制. 本次教程将演示,Blend中路径的常规用法. 1 ...

  8. 更改Activity的最底层的布局

    public void attachToActivity(Activity activity) { mActivity = activity; TypedArray a = activity.getT ...

  9. WEB 3D SVG CAD 向量 几个实施

    一.他们所有的发展.从地上爬起来 VML+SVG发展矢量地图.你并不需要导入第三方的图片作为背景,直接在地图编辑器可以在底图内容编辑,由于岩石.巷道.煤层.画水.础地图样子再在其上面画出智慧线等设备, ...

  10. 白板编程浅谈——Why, What, How(转)

    原文链接:http://lucida.me/blog/whiteboard-coding-demystified/ 这篇文章节选自我正在撰写的一本关于应届生面试求职的书籍,欢迎在评论或微博(@peng ...