Marriage Match III

Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2143    Accepted Submission(s): 646

Problem Description
Presumably, you all have known the question of stable marriage match. A girl will choose a boy; it is similar as the ever game of play-house . What a happy time as so many friends play 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. As 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. On the other hand, in order to play more times of marriage match, every girl can accept any K boys. If a girl chooses a boy, the boy must accept her unconditionally whether they had quarreled before or not.

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 an integer T, means the number of test cases. 
Each test case starts with three integer n, m, K and f in a line (3<=n<=250, 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 1 2
1 1
2 3
3 2
4 2
4 4
1 4
2 3
 
Sample Output
3
 
Author
starvae
 
Source
 题意:
有n个女生n个男生,每个女生可以和她喜欢的男生配对也可以和她的朋友喜欢的男生配对还可以和不超过k个不喜欢的男生配对,当所有的人都配对了时游戏结束,要求每一轮游戏中互相已经配对的两个人以后就不能再配对了问可以进行多少轮游戏。
输入t组数据
输入n,m,k,f,表示n对人,m个喜欢关系,f个朋友关系
输入m行a b 表示女生a喜欢男生b
输入f行a b 表示女生a和女生b是朋友
代码:
//和上一道题类似,只不过是加了每个女生可以选k个不喜欢的男生这一条件,类似上一题建图,然后把女生拆点容量为k
//拆点后的点连向她不喜欢的男生容量为1,然后就一样了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=;
const int inf=0x7fffffff;
int mp[maxn][maxn],fat[maxn];
int find(int x){
return fat[x]==x?x:fat[x]=find(fat[x]);
}
void connect(int x,int y){
int xx=find(x),yy=find(y);
if(xx!=yy) fat[yy]=xx;
}
struct Edge{
int from,to,cap,flow;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct Dinic{
int n,m,s,t;
vector<Edge>edges;
vector<int>g[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
void init(int n){
this->n=n;
for(int i=;i<n;i++) g[i].clear();
edges.clear();
}
void Addedge(int from,int to,int cap){
edges.push_back(Edge(from,to,cap,));
edges.push_back(Edge(to,from,,));//反向弧
m=edges.size();
g[from].push_back(m-);
g[to].push_back(m-);
}
bool Bfs(){
memset(vis,,sizeof(vis));
queue<int>q;
q.push(s);
d[s]=;
vis[s]=;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=;i<(int)g[x].size();i++){
Edge &e=edges[g[x][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=;
d[e.to]=d[x]+;
q.push(e.to);
}
}
}
return vis[t];
}
int Dfs(int x,int a){
if(x==t||a==) return a;
int flow=,f;
for(int&i=cur[x];i<(int)g[x].size();i++){
Edge &e=edges[g[x][i]];
if(d[x]+==d[e.to]&&(f=Dfs(e.to,min(a,e.cap-e.flow)))>){
e.flow+=f;
edges[g[x][i]^].flow-=f;
flow+=f;
a-=f;
if(a==) break;
}
}
return flow;
}
int Maxflow(int s,int t){
this->s=s;this->t=t;
int flow=;
while(Bfs()){
memset(cur,,sizeof(cur));
flow+=Dfs(s,inf);
}
return flow;
}
}dc;
bool solve(int k,int n,int mid){
dc.init(*n+);
for(int i=;i<=n;i++){
dc.Addedge(,i,mid);
dc.Addedge(i,i+n,k);
for(int j=*n+;j<=*n;j++){
if(mp[i][j])
dc.Addedge(i,j,);
else dc.Addedge(i+n,j,);
}
dc.Addedge(i+*n,*n+,mid);
}
return n*mid==dc.Maxflow(,*n+);
}
int main()
{
int t,n,m,k,f;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&m,&k,&f);
int a,b;
memset(mp,,sizeof(mp));
for(int i=;i<=n;i++) fat[i]=i;
for(int i=;i<=m;i++){
scanf("%d%d",&a,&b);
mp[a][b+*n]=;
}
for(int i=;i<=f;i++){
scanf("%d%d",&a,&b);
connect(a,b);
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(find(i)==find(j))
for(int k=*n+;k<=*n;k++)
mp[i][k]=mp[j][k]=(mp[i][k]||mp[j][k]);
}
}
int l=,r=n,mid,ans=;
while(l<=r){
mid=(l+r)/;
if(solve(k,n,mid)){
ans=mid;
l=mid+;
}
else r=mid-;
}
printf("%d\n",ans);
}
return ;
}

HDU 3277 最大流+二分的更多相关文章

  1. HDU 3081 最大流+二分

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

  2. hdu 3228 (最大流+二分)

    题意:一共有N个城市,一些城市里有金矿,一些城市里有仓库,金矿和仓库都有一个容量,有M条边,每条边是双向的,有一个权值,求将所有金矿里的储量都运送到仓库中,所需要经过的道路中,使最大的权值最小 思路: ...

  3. HDU 3277 Marriage Match III(二分+最大流)

    HDU 3277 Marriage Match III 题目链接 题意:n个女孩n个男孩,每一个女孩能够和一些男孩配对,此外还能够和k个随意的男孩配对.然后有些女孩是朋友,满足这个朋友圈里面的人.假设 ...

  4. HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)

    HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...

  5. HDU 1532 最大流入门

    1.HDU 1532 最大流入门,n个n条边,求第1点到第m点的最大流.只用EK做了一下. #include<bits/stdc++.h> using namespace std; #pr ...

  6. Risk UVA - 12264 拆点法+最大流+二分 最少流量的节点流量尽量多。

    /** 题目:Risk UVA - 12264 链接:https://vjudge.net/problem/UVA-12264 题意:给n个点的无权无向图(n<=100),每个点有一个非负数ai ...

  7. hdu 3277(二分+最大流+拆点+离线处理+模板问题...)

    Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. HDU 3277 Marriage Match III(并查集+二分答案+最大流SAP)拆点,经典

    Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total ...

随机推荐

  1. MySql优化浅析

    优化点:合理的使用索引,可以大幅度提升sql查询效率,特别查询的表的数据量大的时候,效果明显.一.引言 公司的产品XX出行上线正式运营,随着数据量的变大,司机2000+,日订单1万+,注册乘客26W+ ...

  2. Scala学习笔记之Actor多线程与线程通信的简单例子

    题目:通过子线程读取每个文件,并统计单词数,将单词数返回给主线程相加得出总单词数 package review import scala.actors.{Actor, Future} import s ...

  3. DeepLearning Intro - sigmoid and shallow NN

    This is a series of Machine Learning summary note. I will combine the deep learning book with the de ...

  4. [精通Python自然语言处理] Ch1 - 将句子切分为单词

    实验对比了一下三种切分方式: 1,2 : nltk.word_tokenize :  分离缩略词,(“Don't” =>'Do', "n't") 表句子切分的“,” &quo ...

  5. kaldi - Online Audio Server(服务器客户端建立方法-旧版在线解码)

    目录 一.服务器客户端识别系统建立方法 1. Command line to start the server(服务器端启动方式): 2. Command line to start the clie ...

  6. Agri-Net(最小生成树)

    Description Farmer John has been elected mayor of his town! One of his campaign promises was to brin ...

  7. 哈希表 STL map

    计数排序时我们使用一个数组来记录出现的数字的次数,而当数据范围太大时,无法建立一个那么大地数组(而且可能空间利用率很低,太浪费),此时可以改用hash table . binary search tr ...

  8. WinForm连续点击按钮只打开一次窗体

    许多朋友,学习C#时,制作WinForm小程序总会有一个问题,如果我们在父窗体设置的是点击一个按钮,打开一个子窗体,连续点击总会连续出现一样窗体,可是我们有时只想打开一次窗体,怎么办? 呵呵,我来方法 ...

  9. Vue于React特性简单对比(一)

    一,对象实体对比 vue的对象实体依然是html,而react的对象实体已经变味jsx,一种新的语法结构. vue的html与react的jsx都可以进行拆分,拆分成更细小的组件,组件之间可以传值. ...

  10. Dom的样式操作和属性操作

    如果说web的研究对象是html和css,那么整个dom结构,包含html树和dom树的dom结构才是研究对象,而在整个页面呈现上面,js起到的作用则是异步的用户行为. 按照上面整个思路,获取dom元 ...