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. python简单循环生成器

    import time #循环生成器 def traversal_list(alist, i): while True: length = len(alist) i = i%(length) yiel ...

  2. [C++] Class (part 1)

    The fundamental ideas behind classes are data abstraction and encapsulation. Data abstraction is a p ...

  3. Python中package的导入语法

    在Python中,一个目录被称为一个package.import和from语法除了导入module文件之外,还可以导入package,语法如下: # import语法 import dir1.dir2 ...

  4. 第四课——MFC应用程序框架

    一.MFC应用程序类型 上篇文章的彩蛋:可通过使用MFC应用程序向导(MFC AppWizard)的功能来创建所需要的应用程序,这意味着不需要输入任何代码.MFC除了应用程序向导,还对应用程序项目有着 ...

  5. Java 变量和输入输出

    一些重要知识 一个源文件里只能有一个public类,其它类数量不限.文件名与public类名相同 JAVA程序严格区分大小写 JAVA应用程序的执行入口是main方法固定写法:public stati ...

  6. (七)类、超类和子类 ——(多态,动态绑定,final类,类型转换,抽象类)

    java中所有的继承都是公有继承. 在子类中的构造其内可以初始化超类的公有域,但不能初始化超类的私有域. 因此需要在子类构造前的第一行使用super()语句初始化超类的私有域. 如果超类没有不带参数的 ...

  7. IIS发布 MVC 配置

    E:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll

  8. c++的一些编程技巧和细节

    1.函数形参,如: CreateProcess(                  NULL,                  cmdbuf,                  NULL,      ...

  9. 父类属性值的copy

    最近开发中遇到这样一个问题将父类的属性值copy到子类中,从而对子类添加一些其他属性. 父类: package com.jalja.org.jms.test01; import java.util.D ...

  10. BZOJ 1854 游戏(二分图匹配或并查集)

    此题的二分图匹配做法很容易想,就是把属性当做s集,武器当做t集,如果该武器拥有该武器则连一条边. 那么答案就是求该二分图的最大前i个匹配.将匈牙利算法改一改,当前找不到增广路就break. 但是过这个 ...