HDU 3277 Marriage Match III

题目链接

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

思路,比HDU3081多了一个条件,此外能够和k个随意的男孩配对。转化为模型,就是多了一个结点,有两种两边的方式。一种连向能够配对的,一种连向不能配对的。此外还要保证流量算在一起,这要怎么搞呢。

事实上拆点就能够了,一个女孩拆成两个点。一个连能够配,一个连不能配,源点连向当中一点,容量为mid,然后两点之间,在连一条边。连接起来,这样就能保证总流量不会超过mid了,其它都和上一题差不不多。只是这题数据比上一题大,要注意一开是预处理关系的做法

代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std; const int MAXNODE = 805;
const int MAXEDGE = 200005; 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 = 205; int t, n, m, k, f, g[N][N], parent[N];
int u[N * N], v[N * N]; int find(int x) {
return x == parent[x] ? x : parent[x] = find(parent[x]);
} bool judge(int mid) {
int s = 0, t = n * 3 + 1;
gao.init(3 * n + 2);
for (int i = 1; i <= n; i++) {
gao.add_Edge(s, i, mid);
gao.add_Edge(i, i + n, k);
gao.add_Edge(i + 2 * n, t, mid);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (g[i][j]) gao.add_Edge(i, j + 2 * n, 1);
else gao.add_Edge(i + n, j + 2 * n, 1);
}
}
return gao.Maxflow(s, t) == n * mid;
} int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d%d%d", &n, &m, &k, &f);
memset(g, 0, sizeof(g));
for (int i = 1; i <= n; i++) parent[i] = i;
for (int i = 0; i < m; i++)
scanf("%d%d", &u[i], &v[i]);
int a, b;
while (f--) {
scanf("%d%d", &a, &b);
int pa = find(a);
int pb = find(b);
if (pa != pb) parent[pa] = pb;
}
for (int i = 0; i < m; i++)
g[find(u[i])][v[i]] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
g[i][j] |= g[find(i)][j];
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 3277 Marriage Match III(二分+最大流)的更多相关文章

  1. HDU 3277 Marriage Match III(并查集+二分答案+最大流SAP)拆点,经典

    Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  2. HDU 3277 Marriage Match III

    Marriage Match III Time Limit: 4000ms Memory Limit: 32768KB This problem will be judged on HDU. Orig ...

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

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

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

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

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

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

  6. 【HDOJ】3277 Marriage Match III

    Dinic不同实现的效率果然不同啊. /* 3277 */ #include <iostream> #include <string> #include <map> ...

  7. HDU 3416 Marriage Match IV (最短路径,网络流,最大流)

    HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...

  8. hdu 3416 Marriage Match IV (最短路+最大流)

    hdu 3416 Marriage Match IV Description Do not sincere non-interference. Like that show, now starvae ...

  9. HDU 3081 Marriage Match II(二分法+最大流量)

    HDU 3081 Marriage Match II pid=3081" target="_blank" style="">题目链接 题意:n个 ...

随机推荐

  1. 改动导航栏上返回button上的字,比如把back改动为返回

    改动导航栏上返回button上的字,比如把back改动为返回 注意:这个须要在跳转之前到视图控制器中写,而不是在跳转之后到控制器中写 UIBarButtonItem *backIetm = [[UIB ...

  2. 组件状态(TComponentState)11种和组件状态(TComponentStyle)4种

    TOperation = (opInsert, opRemove); TComponentState = set of ( csAncestor The component was introduce ...

  3. perl 继承小例子

    <pre name="code" class="html"><pre name="code" class="ht ...

  4. 重操JS旧业第一弹:Script与JS加载

    不管js被包装成什么样子,最终交给浏览器执行的js都是原生的,都离不开原生js的原理. Script标签纸html中用来加载js的标签,我们知道js可以是来自外部,本地,或者内部一段代码,在这里只讨论 ...

  5. Mysql 执行计划分析

    zjdev 正常访问: mysql> explain SELECT temp.* , -> (SELECT COUNT(sn) FROM AssignClientManager WHERE ...

  6. Python标准库:内置函数dict(iterable, **kwarg)

    本函数是从可迭代对象来创建新字典.比方一个元组组成的列表,或者一个字典对象. 样例: #dict() #以键对方式构造字典 d1 = dict(one = 1, two = 2, a = 3) pri ...

  7. cpu性能探究 :cache line 原理

     參考: 一个解说Direct Mapped Cache很深入浅出的文章: http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Memory/dir ...

  8. win32多线程程序设计笔记(第二章)

    第二章线程的第一次接触,主要讲了如何创建线程以及需要注意的几点. 一.创建线程 与调用函数的过程类似;线程只不过用CreateThread的API将函数封装起来,并产生一个与主程序同时执行的程序来调用 ...

  9. HOW TO: How to import UUID function into Postgre 9.3

    1. Open a command console and go to the directory where you installed Postgre server. e.g. D:\Progra ...

  10. STL之涉及到的算法

    一.非变异算法 是一组不破坏操作数据的模板函数,用来对序列数据进行逐个处理.元素查找.子序列搜索.统计和匹配.非变异算法具有极为广泛的适用性,基本上可应用与各种容器. 1查找容器元素find 它用于查 ...