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. [转]notepad++ java编码,输出中文字符时,编译出错

    呆在公司中,最近受开发手机app的几个同事影响,想学android的开发,心血来潮,挡也挡不住,说干就干,直接看教程,发现有很多关于java的语法知识不懂,于是又来学java,学习的过程中难免出现问题 ...

  2. Codeforces 498B Name That Tune 概率dp (看题解)

    Name That Tune 刚开始我用前缀积优化dp, 精度炸炸的. 我们可以用f[ i ][ j ] 来推出f[ i ][ j + 1 ], 记得加加减减仔细一些... #include<b ...

  3. BZOJ3377 [Usaco2004 Open]The Cow Lineup 奶牛序列 其他

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3377 题意概括 给出一个序列,序列中的数字为1~k中的. 让你求最短的非子序列长度. 题解 我们把 ...

  4. BZOJ2843 极地旅行社 LCT

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2843 题意概括 有n座岛 每座岛上的企鹅数量虽然会有所改变,但是始终在[0, 1000]之间.你的 ...

  5. HDU2473 Junk-Mail Filter 并查集

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU2473 题意概括 一堆点. 要你支持合并两组点.分离某组点中的一个,这两种操作. 点数<=100 ...

  6. 6-17 看图写树 uva10562

    非常好的dfs题  有很多细节 关于‘ ’  ‘0’  ’\n‘  的处理  他们都属于isspace函数 其中 while(buf[x+2][i]=='-'&&buf[x+3][i] ...

  7. P2393 yyy loves Maths II

    P2393 yyy loves Maths IIlong double比如保留5位小数*1000000都变成整数最后再/1000000避免精度误差scanf("%Lf",& ...

  8. P1292 倒酒

    P1292 倒酒这个题有很多模型,这个是一个变形.我令一个解为x两个整数Pa和Pb,分别表示从体积为a ml的酒杯中倒出酒的次数和将酒倒入体积为b ml的酒杯中的次数(酒杯一开始为空).b最后是0,所 ...

  9. html 转成 pdf 进行预览、下载、打印

    html 页面转成 pdf,直接看代码: 参考地址: https://github.com/linwalker/render-html-to-pdf 给出代码 方便粘贴: var downPdf = ...

  10. JAVA编程:字符串转为数字求和

    程序从命令行接入数字,求和,如果接入的是字符串的解决办法 设计思想: 首先定义一个double类型的一维数组,然后在定义一个double型的变量sum,并赋值为0,用if循环判断从命令行是否有参数输入 ...