HDU 3081 Marriage Match II 二分 + 网络流
题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女生配对,每轮配对过的人在接下来中都不能配对,求这个k最大是多少。
题解:二分 + 网络流check 。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb emplace_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = ;
const int M = N * N;
int head[N], deep[N], cur[N];
int w[M], to[M], nx[M];
int tot;
void add(int u, int v, int val){
w[tot] = val; to[tot] = v;
nx[tot] = head[u]; head[u] = tot++; w[tot] = ; to[tot] = u;
nx[tot] = head[v]; head[v] = tot++;
}
int bfs(int s, int t){
queue<int> q;
memset(deep, , sizeof(deep));
q.push(s);
deep[s] = ;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = nx[i]){
if(w[i] > && deep[to[i]] == ){
deep[to[i]] = deep[u] + ;
q.push(to[i]);
}
}
}
return deep[t] > ;
}
int Dfs(int u, int t, int flow){
if(u == t) return flow;
for(int &i = cur[u]; ~i; i = nx[i]){
if(deep[u]+ == deep[to[i]] && w[i] > ){
int di = Dfs(to[i], t, min(w[i], flow));
if(di > ){
w[i] -= di, w[i^] += di;
return di;
}
}
}
return ;
} int Dinic(int s, int t){
int ans = , tmp;
while(bfs(s, t)){
for(int i = ; i <= t; i++) cur[i] = head[i];
while(tmp = Dfs(s, t, inf)) ans += tmp;
}
return ans;
} void init(){
memset(head, -, sizeof(head));
tot = ;
}
int pre[N];
int link[N][N];
int edge[M][];
int Find(int x){
if(x == pre[x]) return x;
return pre[x] = Find(pre[x]);
}
int T, n, m, f, s, t, u, v;
void GG(int val){
for(int i = head[s]; ~i; i = nx[i]){
if(i&);
else w[i] = val, w[i+] = ;
}
for(int i = n+; i <= n+n; i++){
for(int j = head[i]; ~j; j = nx[j]){
if(j&);
else w[j] = val, w[j+] = ;
}
}
for(int i = ; i <= n; i++){
for(int j = head[i]; ~j; j = nx[j]){
if(j&);
else w[j] = , w[j+] = ;
}
}
}
int main(){
scanf("%d", &T);
while(T--){
init();
scanf("%d%d%d", &n, &m, &f);
for(int i = ; i <= n; i++){
pre[i] = i;
for(int j = ; j <= n; j++)
link[i][j] = ;
}
for(int i = ; i <= m; i++)
scanf("%d%d", &edge[i][], &edge[i][]);
for(int i = ; i <= f; i++){
scanf("%d%d", &u, &v);
u = Find(u);
v = Find(v);
if(v == u) continue;
pre[u] = v;
}
for(int i = ; i <= m; i++){
int z = Find(edge[i][]);
link[z][edge[i][]] = ;
}
s = , t = * n + ;
for(int i = ; i <= n; i++){
add(s, i, );
int z = Find(i);
for(int j = ; j <= n; j++){
if(link[z][j])
add(i, j+n, );
}
add(i+n,t,);
}
int l = , r = n;
while(l <= r){
int mid = l+r >> ;
GG(mid);
if(Dinic(s,t) == mid*n) l = mid + ;
else r = mid - ;
}
printf("%d\n", l-);
}
return ;
}
HDU 3081 Marriage Match II 二分 + 网络流的更多相关文章
- HDU 3081 Marriage Match II (二分+并查集+最大流)
题意:N个boy和N个girl,每个女孩可以和与自己交友集合中的男生配对子;如果两个女孩是朋友,则她们可以和对方交友集合中的男生配对子;如果女生a和女生b是朋友,b和c是朋友,则a和c也是朋友.每一轮 ...
- 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 pid=3081" target="_blank" style="">题目链接 题意:n个 ...
- 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 最大流OR二分匹配
Marriage Match IIHDU - 3081 题目大意:每个女孩子可以和没有与她或者是她的朋友有过争吵的男孩子交男朋友,现在玩一个游戏,每一轮每个女孩子都要交一个新的男朋友,问最多可以玩多少 ...
- HDU 3081 Marriage Match II (二分+网络流+并查集)
注意 这题需要注意的有几点. 首先板子要快,尽量使用带当前弧优化的dinic,这样跑起来不会超时. 使用弧优化的时候,如果源点设置成0,记得将cur数组从0开始更新,因为有的板子并不是. 其次这题是多 ...
- 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> ...
- Marriage Match II(二分+并查集+最大流,好题)
Marriage Match II http://acm.hdu.edu.cn/showproblem.php?pid=3081 Time Limit: 2000/1000 MS (Java/Othe ...
随机推荐
- DesignPattern系列__01SingletonResponsibility
单一职责原则 单一职责原则:一个类应该只有一个原因引起改变,即一个类应该只负责一个业务逻辑. 问题由来:类T负责t1, t2两个职责,当因为t1j对类T修改的时候,可能导致类T出现问题而影响职责t2. ...
- 基于 Autojs 的 APP、小程序自动化测试 SDK - 2019年8月3日
原文:https://blog.csdn.net/laobingm/article/details/98317394 autojs sdk基于 Autojs 的 APP.小程序自动化测试 SDK,支持 ...
- CMD开放3389端口
REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t R ...
- 分布式ID系列之为什么需要分布式ID以及生成分布式ID的业务需求
为什么需要分布式id生成系统 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID ...
- 章节十五、6-log4 2-用默认的配置
一.实例演示 package log4jtutorial; import org.apache.logging.log4j.LogManager; import org.apache.logging. ...
- C#打开并选择特定类型文件并返回文件名
public string[] GetOpenFileDialogReturnFileFullName(bool multiSelect = false) { ...
- 图像反转(一些基本的灰度变换函数)基本原理及Python实现
1. 基本原理 获取像素值在[0, L]范围内的图像的反转图像,即为负片.适用于增强图像中白色或者灰色的区域,尤其当黑色在图片中占主地位时候 $$T(r) = L-r$$ 2. 运行结果 图源自ski ...
- CSS等分布局方法
原文链接:http://caibaojian.com/css-equal-layout.html CSS等比例划分,在CSS布局中是比较重要的,下面分享几种常用方法和探讨一下兼容性. 一:浮动布局+百 ...
- 素数筛法(Eratosthenes筛法)
介绍 Eratosthenes筛法,又名埃氏筛法,对于求1~n区间内的素数,时间复杂度为n log n,对于10^6^ 以内的数比较合适,再超出此范围的就不建议用该方法了. 筛法的思想特别简单: 对于 ...
- 深入理解 linux磁盘顺序写、随机写
一.前言 ● 随机写会导致磁头不停地换道,造成效率的极大降低:顺序写磁头几乎不用换道,或者换道的时间很短 ● 本文来讨论一下两者具体的差别以及相应的内核调用 二.环境准备 组件 版本 OS Ubunt ...