【HDU3081】Marriage Match II (二分+最大流)
DescriptionPresumably, you all have known the question of stable marriage match. A girl will choose a boy; it is similar as the game of playing house we used to play when we are kids. What a happy time as so many friends playing together. And it is normal that a fight or a quarrel breaks out, but we will still play together after that, because we are kids.
Now, there are 2n kids, n boys numbered from 1 to n, and n girls numbered from 1 to n. you know, ladies first. So, every girl can choose a boy first, with whom she has not quarreled, to make up a family. Besides, the girl X can also choose boy Z to be her boyfriend when her friend, girl Y has not quarreled with him. Furthermore, the friendship is mutual, which means a and c are friends provided that a and b are friends and b and c are friend.
Once every girl finds their boyfriends they will start a new round of this game—marriage match. At the end of each round, every girl will start to find a new boyfriend, who she has not chosen before. So the game goes on and on.
Now, here is the question for you, how many rounds can these 2n kids totally play this game?Input
There are several test cases. First is a integer T, means the number of test cases.
Each test case starts with three integer n, m and f in a line (3<=n<=100,0<m<n*n,0<=f<n). n means there are 2*n children, n girls(number from 1 to n) and n boys(number from 1 to n).
Then m lines follow. Each line contains two numbers a and b, means girl a and boy b had never quarreled with each other.
Then f lines follow. Each line contains two numbers c and d, means girl c and girl d are good friends.Output
For each case, output a number in one line. The maximal number of Marriage Match the children can play.Sample Input
1
4 5 2
1 1
2 3
3 2
4 2
4 4
1 4
2 3Sample Output
2
n个女生与n个男生配对,每个女生只能配对某些男生,有些女生相互是朋友,每个女生也可以跟她朋友能配对的男生配对。
每次配对,每个女生都要跟不同的男生配对且每个女生都能配到对。问最多能配对几轮。(n<=100)
【分析】
二分答案,因为有单调性。然后直接最大流了。输入那里要用并查集。
注意不能直接跑最大流哦,(因为你不知道跑完最大流之后ans是啥啊)
哇塞~TLE了一辈子,dinic中几个不起眼的优化也能是可以挽救你于水火之中啊。比如下面的加粗部分:
int find_flow(int x,int flow)
{
if(x==ed) return flow;
int now=0;
for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
{
int y=t[i].y;
if(dis[y]==dis[x]+1)
{
int a=find_flow(y,mymin(t[i].f,flow-now));
t[i].f-=a;
t[t[i].o].f+=a;
now+=a;
if(now==flow) break;
}
}
if(now==0) dis[x]=-1;
return now;
}
我这个傻逼还因为数组开小了TLE了好一阵子。
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 210
#define Maxm 10010
#define INF 0xfffffff int fa[Maxn],first[Maxn],dis[Maxn];
bool map[Maxn][Maxn]; struct node
{
int x,y,f,o,next;
};
node t[*Maxm],tt[*Maxm];int len; int st,ed;
int n,m,k; int mymin(int x,int y) {return x<y?x:y;} void ins(int x,int y,int f)
{
tt[++len].x=x;tt[len].y=y;tt[len].f=f;
tt[len].next=first[x];first[x]=len;tt[len].o=len+;
tt[++len].x=y;tt[len].y=x;tt[len].f=;
tt[len].next=first[y];first[y]=len;tt[len].o=len-;
} int ffind(int x)
{
if(fa[x]!=x) fa[x]=ffind(fa[x]);
return fa[x];
} queue<int > q;
bool bfs()
{
while(!q.empty()) q.pop();
memset(dis,-,sizeof(dis));
q.push(st);dis[st]=;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=first[x];i;i=t[i].next) if(t[i].f>)
{
int y=t[i].y;
if(dis[y]==-)
{
dis[y]=dis[x]+;
q.push(y);
}
}
}
if(dis[ed]==-) return ;
return ;
} int find_flow(int x,int flow)
{
if(x==ed) return flow;
int now=;
for(int i=first[x];i;i=t[i].next) if(t[i].f>)
{
int y=t[i].y;
if(dis[y]==dis[x]+)
{
int a=find_flow(y,mymin(t[i].f,flow-now));
t[i].f-=a;
t[t[i].o].f+=a;
now+=a;
if(now==flow) break;
}
}
if(now==) dis[x]=-;
return now;
} int max_flow()
{
int ans=;
while(bfs())
ans+=find_flow(st,INF);
return ans;
} bool check(int x)
{
for(int i=;i<=len;i++) t[i]=tt[i];
for(int i=len-*n+;i<=len;i+=) t[i].f=x;
return max_flow()==n*x;
} void finda()
{
int l=,r=n*n;
while(l<r)
{
int mid=(l+r+)>>;
if(check(mid)) l=mid;
else r=mid-;
}
printf("%d\n",l);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
len=;
memset(first,,sizeof(first));
memset(map,,sizeof(map));
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
map[x][y]=;
}
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
fa[ffind(x)]=ffind(y);
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) if(ffind(i)==ffind(j))
{
for(int k=;k<=n;k++) if(map[j][k])
map[i][k]=;
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) if(map[i][j])
ins(i,j+n,);
st=*n+;ed=st+;
for(int i=;i<=n;i++) ins(st,i,INF);
for(int i=;i<=n;i++) ins(i+n,ed,INF);
finda();
}
return ;
}
[HDU3081]
所以现在我的数组是能开多大开多大。
2016-05-29 15:09:33
【HDU3081】Marriage Match II (二分+最大流)的更多相关文章
- hdu3081 Marriage Match II(二分+并查集+最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意: n个女生与n个男生配对,每个女生只能配对某些男生,有些女生相互是朋友,每个女生也可以跟她 ...
- HDU3081 Marriage Match II —— 传递闭包 + 二分图最大匹配 or 传递闭包 + 二分 + 最大流
题目链接:https://vjudge.net/problem/HDU-3081 Marriage Match II Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)
HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...
- HDU3081:Marriage Match II (Floyd/并查集+二分图匹配/最大流(+二分))
Marriage Match II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- Marriage Match II(二分+并查集+最大流,好题)
Marriage Match II http://acm.hdu.edu.cn/showproblem.php?pid=3081 Time Limit: 2000/1000 MS (Java/Othe ...
- hdu3081 Marriage Match II(最大流)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Marriage Match II Time Limit: 2000/1000 M ...
- HDU 3081 Marriage Match II 二分 + 网络流
Marriage Match II 题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女 ...
- HDU 3081 Marriage Match II (二分+并查集+最大流)
题意:N个boy和N个girl,每个女孩可以和与自己交友集合中的男生配对子;如果两个女孩是朋友,则她们可以和对方交友集合中的男生配对子;如果女生a和女生b是朋友,b和c是朋友,则a和c也是朋友.每一轮 ...
- hdu3081 Marriage Match II
新年第一篇,又花了一早上,真是蠢啊! 二分+网络流 之前对于讨论哪些人是朋友的时候复杂度过高 直接n3的暴力虽然看起来复杂度高,其实并不是每次都成立 #include<bits/stdc++.h ...
- HDU 3081 Marriage Match II(二分法+最大流量)
HDU 3081 Marriage Match II pid=3081" target="_blank" style="">题目链接 题意:n个 ...
随机推荐
- pcap文件格式
pcap文件格式 pcap文件格式是bpf保存原始数据包的格式,很多软件都在使用,比如tcpdump.wireshark等等,了解pcap格式可以加深对原始数据包的了解,自己也可以手工构造任意的数 ...
- CocoaPods导入第三方库头文件自动补齐
使用了一段时间CocoaPods来管理Objective-c的类库,方便了不少.但是有一个小问题,当我在xcode输入import关键字的时候,没有自动联想补齐代码的功能,需要手工敲全了文件名,难以适 ...
- Android自定义DataTimePicker(日期选择器)
实现的效果就是在同一个布局上显示日期选择和时间选择,时间不准确bug修复 1.自定义类DateTimePickDialogUtil.java public class DateTimePickDial ...
- GUI编程笔记(java)04:GUI(HelloWorld)窗体案例
1.Frame 在JAVA中,Frame是一种控件,可作为父窗体加载其他swing控件.案例: package cn.itcast_01; import java.awt.Frame; public ...
- js--小结⑤
js中的for循环,while循环,do...while循环和C语言的一模一样 有几个问题要提醒一下的是 1. null是对象,即object undefined是undefined d ...
- a标签的简单用法
1.href="#"的作用:页面中有滚动,可以直接回到顶部. <a href="#">回到最顶端</a> 2.href="ur ...
- angularjs小知识
字符串和对象的转化 :angular.fromJson(jsonStr) 对象转字符串 :angular.toJson(obj) jsonStr:json字符串 obj:对象
- js--Ajax的小知识(二):处理ajax的session过期的请求
问题的产生: 现如今Ajax在Web项目中应用广泛,几乎可以说无处不在. 有时会碰到这样个问题:当Ajax请求遇到Session超时,应该怎么办? 显而易见,传统的页面跳转在此已经不适用,因为Ajax ...
- [Twisted] 部署Twisted
Twisted提供了基础设施,来实现可重用.可配置的方式来部署. 1.Service Twisted使用Service来实现了许多协议,如TCP,FTP,HTTP,SSH等. 实现的IService接 ...
- C++专题 - 面向对象总结
1. 什么是类?什么是对象?对象与类的关系是什么? 答:类就是相同的数据和相同的一组对象的集合,即类是对具有相同数据结构和相同操作的一类对象的描述: 对象是描述其属性的数据以及对这些数 ...