Marriage Match III

Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1581    Accepted Submission(s): 464

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
题意:共同拥有2*n个人。一半女一半男,女与男有m个关系。表示能够成为一对,接下来 f 对女的与女的  的朋友关系,假设a与b是朋友。那么表示a女与b女的相连男性也能够成为一对,相同b也与a的相连男性可成为一对,女的之间的朋友关系能够传递。且每一个女性能够再随意选择K人。

一组配对情况为全部的女性都有一个与之配对的男性(一对一的关系)。假设还有其它组配对情况,那么全部的女性配对不能够再与原来的男性配成对。问最多有多少组配对情况。


 这题和HDU3081 非常类似。



可是由于能够任意选择K个人。



所以要将女孩拆成两个点。



将每一个女孩u分为u1,u2。若u喜欢v则加一条u1到v的边 否则加一条u2到v的边。令加u1到u2的容量为k的边;



这个拆点的想法很巧妙。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define captype int const int MAXN = 100010; //点的总数
const int MAXM = 4000100; //边的总数
const int INF = 1<<30;
struct EDG{
int to,next;
captype cap,flow;
}edg[MAXM];
int eid,head[MAXN];
int gap[MAXN];
int dis[MAXN];
int cur[MAXN];
int pre[MAXN]; void init(){
eid=0;
memset(head,-1,sizeof(head));
}
void addEdg(int u,int v,captype c,captype rc=0){
edg[eid].to=v; edg[eid].next=head[u];
edg[eid].cap=c; edg[eid].flow=0; head[u]=eid++; edg[eid].to=u; edg[eid].next=head[v];
edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++;
}
captype maxFlow_sap(int s,int t,int n){
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
pre[s]=-1;
gap[0]=n; captype ans=0;
int u=s;
while(dis[s]<n){
if(u==t){
captype mint=INF;
int id;
for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to])
if(mint>edg[i].cap-edg[i].flow){
mint=edg[i].cap-edg[i].flow;
id=i;
}
for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]){
edg[i].flow+=mint;
edg[i^1].flow-=mint;
}
ans+=mint;
u=edg[id^1].to;
continue;
}
bool flag=0;
for(int i=cur[u]; i!=-1; i=edg[i].next)
if(edg[i].cap>edg[i].flow&&dis[u]==dis[edg[i].to]+1){
cur[u]=pre[edg[i].to]=i;
flag=true;
break;
}
if(flag){
u=edg[cur[u]].to;
continue;
}
int minh=n;
for(int i=head[u]; i!=-1; i=edg[i].next)
if(edg[i].cap>edg[i].flow && minh>dis[edg[i].to]){
cur[u]=i; minh=dis[edg[i].to];
}
gap[dis[u]]--;
if(!gap[dis[u]]) return ans;
dis[u]=minh+1;
gap[dis[u]]++;
if(u!=s)
u=edg[pre[u]^1].to;
}
return ans;
} int fath[MAXN];
int findroot(int x){
if(x!=fath[x])
fath[x]=findroot(fath[x]);
return fath[x];
}
void setroot(int x,int y){
x=findroot(x);
y=findroot(y);
fath[x]=y;
}
void rebuildMap(int mapt[255][255],int n){//处理朋友之间的关系
int mp[255][255]={0};
for(int i=1; i<=n; i++)
fath[i]=findroot(i);
for(int i=1; i<=n; i++){
int j=fath[i];
for(int e=1; e<=n; e++)
mp[j][e]|=mapt[i][e];
}
for(int i=1; i<=n; i++){
int j=fath[i];
for(int e=1; e<=n; e++)
mapt[i][e]=mp[j][e];
}
}
int main()
{
int T,n,m,k,f,mapt[255][255];
int u,v;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&n,&m,&k,&f); init();
memset(mapt,0,sizeof(mapt));
for(int i=1; i<=n; i++)
fath[i]=i; while(m--){
scanf("%d%d",&u,&v);
mapt[u][v]=1;
}
while(f--){
scanf("%d%d",&u,&v);
setroot(u,v);
}
rebuildMap(mapt,n); int s=0, t=3*n+1;
for(int i=1; i<=n; i++){
addEdg(s,i,0);
addEdg(i,i+n,k);
for(int j=1; j<=n; j++)
if(mapt[i][j])
addEdg(i,j+2*n,1);
else
addEdg(i+n,j+2*n,1); addEdg(i+2*n,t,0);
} int ans=0 , l=0 , r=n ,mid;
while(l<=r){
mid=(l+r)>>1; for(int i=0; i<eid; i++)
edg[i].flow=0;
for(int i=head[s]; i!=-1; i=edg[i].next)
edg[i].cap=mid;
for(int i=head[t]; i!=-1; i=edg[i].next)
edg[i^1].cap=mid; if(n*mid==maxFlow_sap(s,t,t+1))
ans=mid,l=mid+1;
else
r=mid-1;
} printf("%d\n",ans);
}
}

HDU 3277 Marriage Match III(并查集+二分答案+最大流SAP)拆点,经典的更多相关文章

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

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

  2. HDU 3277 Marriage Match III

    Marriage Match III Time Limit: 4000ms Memory Limit: 32768KB This problem will be judged on HDU. Orig ...

  3. Marriage Match II 【HDU - 3081】【并查集+二分答案+最大流】

    题目链接 一开始是想不断的把边插进去,然后再去考虑我们每次都加进去边权为1的边,直到跑到第几次就没法继续跑下去的这样的思路,果不其然的T了. 然后,就是想办法咯,就想到了二分答案. 首先,我们一开始处 ...

  4. HDU 3416 Marriage Match IV (最短路径,网络流,最大流)

    HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...

  5. hdu 4750 Count The Pairs(并查集+二分)

    Problem Description With the 60th anniversary celebration of Nanjing University of Science and Techn ...

  6. 【HDOJ】3277 Marriage Match III

    Dinic不同实现的效率果然不同啊. /* 3277 */ #include <iostream> #include <string> #include <map> ...

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

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

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

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

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

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

随机推荐

  1. 和组合数有关的dp

    1. UVaLive 7143 Room Assignment 用dp[i][r]表示,前i个盒子已经放完了,手上还拿着r对同色球. 状态转移方程为:dp[i+1][r-a-b] = dp[i][r] ...

  2. Codeforces Round #317 (div 2)

    Problem A Arrays 思路:水一水. #include<bits/stdc++.h> using namespace std; ; int n1,n2,k,m,a[N],b[N ...

  3. 如何删除jsPlumb连接

    I am playing with jsplumb, but I am not able to delete the connection between two divs having only t ...

  4. 【Java】 剑指offer(58-1) 翻转单词顺序

      本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变 ...

  5. ACM题目中的时间限制与内存限制 复杂度的估计

    运行时限为1s,这很常见,对于该时限,我们设计的算法复杂度不能超过百万级别,即不要超过一千万.假如你的算法时间复杂度为O(n^2),则n不应该大于3000 空间限制是32MB,即你程序中申请的内存不能 ...

  6. POJ 1375 Intervals 光源投影【平面几何】

    <题目链接> <转载于> 题目大意: 给一个光源点s,给一些圆,源点和s相切会形成阴影,求每一段阴影在横轴上的区间. 解题分析: 这道其实不需要点与圆切线的板子来求解,完全可以 ...

  7. 洛谷P2347 砝码称重 【多重背包】(方案数)(经典)

    题目链接:https://www.luogu.org/problemnew/show/P2347 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入 ...

  8. Linux 运行Python文件,不因终端关闭而终止运行

    在Linux服务器运行py文件时,有时会因为终端窗口的关闭而结束py文件的执行,这时候使用下面的命令运行py文件: $nohup python filename.py & 命令解释: nohu ...

  9. MySQL中查询获取每个班级成绩前三名的学生信息

    CREATE TABLE t_testscore( pk_id INT PRIMARY KEY, c_name VARCHAR(50) , c_score INT, c_class INT )DEFA ...

  10. BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)

    题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...