题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3081

推荐博客:https://www.cnblogs.com/liuxin13/p/4728131.html

这个题目没什么思路,完全不知道怎么写,后来看了题解,说是网络流+二分+并查集,然后更加懵了。

然后就z继续看了详细解答,才知道怎么去写。

emmm...这个题目他是让你求不同男孩女孩全部都成功配对最多会有多少轮,每一轮的女孩配对的男生都不一样。

还有一个让题目复杂一点的就是女孩子有朋友,在一个女孩圈里,她朋友没吵过架的男生在下一轮里可以成为她的男朋友。

先不考虑女孩子有女孩圈里,也不求最多有多少轮,就是男生女生要全部成功配对,那就是一个网络流的裸题。

但是呢,现在要求最多有多少轮(不考虑女孩圈),那其实也很难想到二分。。。

不过有人提示你用二分了,这个就觉得二分可以做,而且感觉也特别对,那就这样写吧,至于解释就是一般求最值都要想到用二分,

而且这个还是可以找到单调性,这个单调性就是如果最大流==n*x(x是被二分枚举的答案)那就说明这个可以是答案,当然也可以更大一点,所以就更新这个l=mid+1

不然就是这个mid大了,所以这个r就更新为mid-1。

最后就是考虑有女孩圈了,既然有女孩圈,是一个圈,那就容易想到并查集,所以这个题目的第三个算法就是并查集,

但是这个并查集怎么用,我开始也不知道,后来看了一点点别人写的代码才理解的,这个就是把一个把一个圈子的女孩的所有男朋友都连到根节点上去。

这个样子,以后每一个女孩找男朋友都可以通过根节点去连线(建图)

大致思路就是这个样子的,接下来敲代码了。

非常郁闷,又找了一个晚上的bug,唉,好伤心,好想哭。。。。

最后还是刷牙的时候感觉自己的问题,我这么写很可能会同一边输入很多次,这个需要判断一下,哭了。。。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5+; struct edge
{
int u, v, c, f;
edge(int u, int v, int c, int f) :u(u), v(v), c(c), f(f) {}
};
vector<edge>e;
vector<int>G[maxn];
int level[maxn];//BFS分层,表示每个点的层数
int iter[maxn];//当前弧优化
int m;
void init()
{
for (int i = ; i <= maxn; i++)G[i].clear();
e.clear();
}
void addedge(int u, int v, int c)
{
e.push_back(edge(u, v, c, ));
e.push_back(edge(v, u, , ));
m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
void BFS(int s)//预处理出level数组
//直接BFS到每个点
{
memset(level, -, sizeof(level));
queue<int>q;
level[s] = ;
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
for (int v = ; v < G[u].size(); v++)
{
edge& now = e[G[u][v]];
if (now.c > now.f && level[now.v] < )
{
level[now.v] = level[u] + ;
q.push(now.v);
}
}
}
}
int dfs(int u, int t, int f)//DFS寻找增广路
{
if (u == t)return f;//已经到达源点,返回流量f
for (int &v = iter[u]; v < G[u].size(); v++)
//这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历
//在每次找增广路的时候,数组要清空
{
edge &now = e[G[u][v]];
if (now.c - now.f > && level[u] < level[now.v])
//now.c - now.f > 0表示这条路还未满
//level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想
{
int d = dfs(now.v, t, min(f, now.c - now.f));
if (d > )
{
now.f += d;//正向边流量加d
e[G[u][v] ^ ].f -= d;
//反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到
return d;
}
}
}
return ;
}
int Maxflow(int s, int t)
{
int flow = ;
for (;;)
{
BFS(s);
if (level[t] < )return flow;//残余网络中到达不了t,增广路不存在
memset(iter, , sizeof(iter));//清空当前弧数组
int f;//记录增广路的可增加的流量
while ((f = dfs(s, t, INF)) > )
{
flow += f;
}
}
return flow;
} int f[maxn], boy[maxn], girl[maxn];
vector<int>love[maxn]; int findx(int x)
{
return f[x] == x ? x : f[x] = findx(f[x]);
} void unite(int x,int y)
{
x = findx(x);
y = findx(y);
if (x == y) return;
f[x] = y;
}
int n;
bool vis[][];
void buildgrath(int flow,int s,int t)
{
init();
memset(vis, , sizeof(vis));
for(int i=;i<=n;i++)
{
if(!vis[s][i]) addedge(s, i, flow);
if(!vis[i+n][t]) addedge(i + n, t, flow); int u = findx(i);
int len = love[u].size(); for(int j=;j<len;j++)
{
if (vis[i][love[u][j]]) continue;
addedge(i, love[u][j], );
vis[i][love[u][j]] = ;
}
}
} int main()
{
int w;
scanf("%d", &w);
while(w--)
{
int m, fx;
scanf("%d%d%d", &n, &m, &fx);
for (int i = ; i <= *n+; i++)
{
f[i] = i;
love[i].clear();
}
for(int i=;i<=m;i++)
{
scanf("%d%d", &girl[i], &boy[i]);
}
for(int i=;i<=fx;i++)
{
int x, y;
scanf("%d%d", &x, &y);
unite(x, y);
}
int s = , t = n + n + ;
int l = , r = n;
for(int i=;i<=m;i++)
{
int u = findx(girl[i]);
love[u].push_back(boy[i] + n);
}
int ans = ;
while(l<=r)
{
int mid = (l + r) >> ;
buildgrath(mid, s, t);
int ex = Maxflow(s, t);
if(ex==n*mid)
{
l = mid + ;
ans = mid;
}
else r = mid - ;
}
printf("%d\n", ans);
}
return ;
}

N - 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 二分 + 网络流

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

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

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

  4. HDU3081:Marriage Match II (Floyd/并查集+二分图匹配/最大流(+二分))

    Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  5. hdu3081 Marriage Match II(最大流)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Marriage Match II Time Limit: 2000/1000 M ...

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

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

  7. Marriage Match II(二分+并查集+最大流,好题)

    Marriage Match II http://acm.hdu.edu.cn/showproblem.php?pid=3081 Time Limit: 2000/1000 MS (Java/Othe ...

  8. HDU3081 Marriage Match II —— 传递闭包 + 二分图最大匹配 or 传递闭包 + 二分 + 最大流

    题目链接:https://vjudge.net/problem/HDU-3081 Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    ...

  9. 【HDU3081】Marriage Match II (二分+最大流)

    Description Presumably, you all have known the question of stable marriage match. A girl will choose ...

随机推荐

  1. 拓扑排序入门详解&&Educational Codeforces Round 72 (Rated for Div. 2)-----D

    https://codeforces.com/contest/1217 D:给定一个有向图,给图染色,使图中的环不只由一种颜色构成,输出每一条边的颜色 不成环的边全部用1染色 ps:最后输出需要注意, ...

  2. E. 数字串

    给你一个长度为 n 的数字串,找出其中位数不超过15位的不包含前导0和后导0的数 x ,使得 x+f(x) 是一个回文数,其中 f(x) 表示将 x 反转过来的数. 输入格式 多组输入,处理到文件结束 ...

  3. JS:document.documentElement对象的

    document.documentElement.clientWidth 获取浏览器窗口文档显示区域的宽度,不包括滚动条. document.documentElement.clientHeight ...

  4. vim环境下空格和tab键互换

    对于已保存的文件,可以使用下面的方法进行空格和TAB的替换 TAB替换为空格::set ts=4:set expandtab:%retab! 空格替换为TAB::set ts=4:set noexpa ...

  5. 前端基础-HTML(2)

    1. 什么是标签以及标签的分类: 在HTML页面中,带有“< >”符号的元素被称为HTML标签,如上节提到的 <HTML>.<head>.<body>都 ...

  6. 2019-2020-1 20199328《Linux内核原理与分析》第五周作业

    实验要求: 实验步骤: 这里以20号系统调用getpid为例进行实验,该函数的功能为:返回当前进程标识. getpid.c代码: 查看实验结果: 当前进程pid为:31042. 在C语言中编入汇编代码 ...

  7. c++中set 的用法

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  8. eclipse自动补全导致变量会跟上String后缀的问题解决

    https://blog.csdn.net/feinifi/article/details/103665860

  9. SaltStack的数据系统

    一.SaltStack数据系统的分类 1.Grains(收集的是静态数据) 官方使用文档:https://www.unixhot.com/docs/saltstack/topics/targeting ...

  10. Django 内置分页的简单使用

    1, 文档 https://docs.djangoproject.com/en/1.11.1/topics/pagination/ 2,视图 from django.core.paginator im ...