HDU 3081 Marriage Match II(二分法+最大流量)
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(二分法+最大流量)的更多相关文章
- HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)
HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...
- HDU 3081 Marriage Match II (二分图,并查集)
HDU 3081 Marriage Match II (二分图,并查集) Description Presumably, you all have known the question of stab ...
- HDU 3081 Marriage Match II 二分 + 网络流
Marriage Match II 题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女 ...
- HDU 3081 Marriage Match II 最大流OR二分匹配
Marriage Match IIHDU - 3081 题目大意:每个女孩子可以和没有与她或者是她的朋友有过争吵的男孩子交男朋友,现在玩一个游戏,每一轮每个女孩子都要交一个新的男朋友,问最多可以玩多少 ...
- HDU - 3081 Marriage Match II 【二分匹配】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意 有n对男女 女生去选男朋友 如果女生从来没和那个男生吵架 那么那个男生就可以当她男朋友 女 ...
- HDU 3081 Marriage Match II
二分图的最大匹配+并查集 每次匹配完之后,删除当前匹配到的边. #include<cstdio> #include<cstring> #include<cmath> ...
- HDU 3081 Marriage Match II (二分+并查集+最大流)
题意:N个boy和N个girl,每个女孩可以和与自己交友集合中的男生配对子;如果两个女孩是朋友,则她们可以和对方交友集合中的男生配对子;如果女生a和女生b是朋友,b和c是朋友,则a和c也是朋友.每一轮 ...
- HDU 3081 Marriage Match II (二分+网络流+并查集)
注意 这题需要注意的有几点. 首先板子要快,尽量使用带当前弧优化的dinic,这样跑起来不会超时. 使用弧优化的时候,如果源点设置成0,记得将cur数组从0开始更新,因为有的板子并不是. 其次这题是多 ...
- hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //灵活运用最大流量
3081 意甲冠军: n女生选择不吵架,他甚至男孩边(他的朋友也算.并为您收集过程).2二分图,一些副作用,有几个追求完美搭配(每场比赛没有重复的每一个点的比赛) 后.每次增广一单位,(一次完美匹配) ...
随机推荐
- SDL2源码分析5:更新纹理(SDL_UpdateTexture())
===================================================== SDL源码分析系列文章列表: SDL2源码分析1:初始化(SDL_Init()) SDL2源 ...
- codeforces293E (树上点分治+树状数组)
和poj1747相比起来,只不过是限制条件多了一维. 而多了这一维,所以需要用树状数组来维护,从而快速得到答案. 因为没注意传进树状数组函数的参数可能是<=0的,导致超时了好久. #pragma ...
- nginx subrequest演示示例程序
只有简单subrequest应用演示示例. nginx.conf文件: #user nobody; worker_processes 1; #error_log logs/error.log; #er ...
- libyuv编
下载代码(墙): git clone http://git.chromium.org/external/libyuv.git 用 make 编译(linux.mingw.cygwin): mak ...
- 【剑指offer】两个队列实现堆栈
转载请注明出处:http://blog.csdn.net/ns_code/article/details/25076689 题目:用两个队列模拟一个栈,即用两个队列的出队和入队操作.来实现栈的 ...
- Quartz.NET学习系列
Quartz.NET它是一个开源的任务调度引擎,对于周期性任务,持久性任务提供了很好的支持,并且支持持久性.集群等功能. 这是什么对我来说Quartz.NET学习记录: 源代码下载http://yun ...
- 安卓的sqlite增删改
基于安卓的sqlite增删改,笔记学习: 1.使用LinearLayout 布局生成,增删改的页面如图 代码布局如下: <LinearLayout xmlns:android="htt ...
- ajax方式提交带文件上传的表单,上传后不跳转
ajax方式提交带文件上传的表单 一般的表单都是通过ajax方式提交,所以碰到带文件上传的表单就比较麻烦.基本原理就是在页面增加一个隐藏iframe,然后通过ajax提交除文件之外的表单数据,在表单数 ...
- 【DP|多重背包可行性】POJ-1014 Dividing
Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...
- 认识Backbone (一)
Backbone.js为复杂WEB应用程序提供模型(models).集合(collections).视图(views)的结构.其中模型用于绑定键值数据和自定义事件:集合附有可枚举函数的丰富API: 视 ...