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. Debian/Ubuntu Linux 下安装LLVM/Clang 编译器

    第一步,首先编辑 /etc/apt/sources.list,增加下面源: (加入源后务必执行apt-get update,假设有错误提示,先执行第二步,然后apt-get update) Debia ...

  2. memset,memcpy,memmove,strcpy,strcat,strcmp的实现(其实很简单,每个程序都只有几行代码)

    面试中的几个小问题 1.对stl中list封装(参考1): 2.对重要C函数实现(参考2): //memset void *memset(void *buffer, int c, int count) ...

  3. 基于visual Studio2013解决C语言竞赛题之1079狼羊过河

        题目 解决代码及点评 /************************************************************************/ /* ...

  4. 14.8.1 Enabling File Formats

    14.8 InnoDB File-Format Management 14.8.1 Enabling File Formats 14.8.2 Verifying File Format Compati ...

  5. oracle 表连接 - hash join 哈希连接

    一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...

  6. 关于iOS7以后版本号企业公布问题

    大家都知道,苹果在公布7.1以后,不打个招呼就把企业公布方式给换掉了(谴责一下~) 曾经普通server+web页面+ipa+plist就能够搞定,如今已经不行了. 关于如今企业公布教程网上贴出来了非 ...

  7. MFC--自定义消息

    在windows程序中,消息是一个重要的概念,最常见的消息一般都是以WM_开头,WM就是window message,窗口消息的缩写,通过处理标准的windows消息,我们可以改变窗口的外观,如使用W ...

  8. MFC/VC CxImage 简单配置与使用 (完整版)

    如果本篇文章还不能解决你在生成解决方案以及便宜过程中的问题 请参阅: http://blog.csdn.net/afterwards_/article/details/7997385 我个人配置过来成 ...

  9. Delphi 模拟网站验证码(酷,把随机文字写道图片上)

    function TfrmLabelPages.PwdImg(img: Timage): string; var I,j,k: Integer; vPoint: TPoint; vLeft: Inte ...

  10. 默认情况下,不使用of子句表示在select所有的数据表中加锁(转)

    Select …forupdate语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句也不 ...