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. PAT 1002 Hello World for U (20)

    Given any string of N (>=5) characters, you are asked to form the characters into the shape of U. ...

  2. MongoDB系列之三(副本集配置)

    今天我测试了一下MongoDB的副本集的配置. 首先从概念上说一下MongoDB副本集和主从复制的区别.其实副本集(Replica Set)是主从复制的高级形式.高级在哪里呢?主动复制实现了数据备份+ ...

  3. Java内部类——成员内部类

    成员内部类的意思就是,一个外层类里面包含着一个非static的class,举例如下: class OuterClass { //变量,函数定义... class InnerClass { //变量,函 ...

  4. Windows Azure使用VS 2010的云应用开发过程

    原文 Windows Azure使用VS 2010的云应用开发过程 作为技术人员,如果在2010还不知道云计算,那么你已经“OUT”了:作为Visual Studio平台的使用者,如果你不知道VS 2 ...

  5. RHEL4 i386下安装rdesktop【原创】

    http://rpmfind.net/ 1.根据系统下载rdesktop (1)查看Linux版本:# lsb_release -aLSB Version: :core-3.0-ia32:core-3 ...

  6. 基于visual Studio2013解决面试题之0708字符串全排列

     题目

  7. 为什么要用BitSet

    BitSet适用于一类型boolean判断,Java的BitSet在这类型判断中非常高效. 举例说明:在判断前2000万数字中素数个数的程序中,如果使用最基本的素数判断代码: package com; ...

  8. sharepoint 2010 在自定义列表的字段上增加功能菜单

    sharepoint 2010 在自定义列表的字段上增加功能菜单方法 打开sharepoint designer 2010,找到需要修改的视图页面,例如allitem.aspx,编辑这个页面,点击高级 ...

  9. 第三天学习内容 if--else

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  10. Servlet的学习之Session(5)

    在上一篇中我们介绍了如果使用Session来做一个简单的用户登录案例,在本篇中我们继续使用Session技术来做一个防止表单重复提交的案例. 这是一个很重要的知识点,在很多框架中都有防止表单重复提交的 ...