职务地址:http://acm.hdu.edu.cn/showproblem.php?

pid=3081

有一段时间没写最大流的题了,这题建图竟然想了好长时间。。。

刚開始是按着终于的最大流即是做多轮数去想建图,结果根本没思路。后来想了想,能够用二分答案的思想来找终于答案。然后非常明显的并查集,可是并查集学的略渣,竟然卡在并查集上了。。= =。 可是也不是并查集的事。

。是我建图的思想太正了,略微用点逆向思维并查集就能够非常好利用了。

建图思路是:建立一个源点与汇点,将女孩与源点相连,男孩与汇点相连,权值均为二分得到的mid,然后将女孩男孩间能够建立关系的相连。权值均为1.最后推断是否满流。

若满流,说明能够。就继续向上找。

代码例如以下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include<algorithm>
using namespace std;
const int INF=1e9;
int head[300], souce, sink, nv, cnt, n;
int cur[300], pre[300], d[300], q[300], bin[300], hash1[200][200], num[300];
struct no
{
int girl, boy;
}chao[20000];
int find1(int x)
{
return bin[x]==x?x:bin[x]=find1(bin[x]);
}
void merger(int x, int y)
{
int f1, f2;
f1=find1(x);
f2=find1(y);
if(f1!=f2)
{
bin[f2]=f1;
}
}
struct node
{
int u, v, cap, next;
}edge[1000000];
void add(int u, int v, int cap)
{
edge[cnt].v=v;
edge[cnt].cap=cap;
edge[cnt].next=head[u];
head[u]=cnt++; edge[cnt].v=u;
edge[cnt].cap=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
void bfs()
{
memset(num,0,sizeof(num));
memset(d,-1,sizeof(d));
int f1=0, f2=0, i;
d[sink]=0;
num[0]=1;
q[f1++]=souce;
while(f1>=f2)
{
int u=q[f2++];
for(i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(d[v]==-1)
{
d[v]=d[u]+1;
num[d[v]]++;
q[f1++]=v;
}
}
}
}
int isap(int mid)
{
memcpy(cur,head,sizeof(cur));
bfs();
int i, u=pre[souce]=souce, flow=0;
while(d[souce]<nv)
{
//printf("%d\n",u);
if(u==sink)
{
int f=INF,pos;
for(i=souce;i!=sink;i=edge[cur[i]].v)
{
if(f>edge[cur[i]].cap)
{
f=edge[cur[i]].cap;
pos=i;
}
}
for(i=souce;i!=sink;i=edge[cur[i]].v)
{
edge[cur[i]].cap-=f;
edge[cur[i]^1].cap+=f;
}
flow+=f;
if(flow>=n*mid)
return flow;
u=pos;
}
for(i=cur[u];i!=-1;i=edge[i].next)
{
if(d[edge[i].v]+1==d[u]&&edge[i].cap)
break;
}
if(i!=-1)
{
cur[u]=i;
pre[edge[i].v]=u;
u=edge[i].v;
}
else
{
if(--num[d[u]]==0) break;
int mind=nv;
for(i=head[u];i!=-1;i=edge[i].next)
{
if(mind>d[edge[i].v]&&edge[i].cap)
{
mind=d[edge[i].v];
cur[u]=i;
}
}
d[u]=mind+1;
num[d[u]]++;
u=pre[u];
}
}
return flow;
}
int main()
{
int t, i, j, a, b, c, m, f;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&f);
for(i=1;i<=n;i++)
{
bin[i]=i;
}
for(i=1;i<=m;i++)
{
scanf("%d%d",&chao[i].girl,&chao[i].boy);
}
while(f--)
{
scanf("%d%d",&a,&b);
merger(a,b);
}
int low=0, high=n, mid, ans, x;
while(low<=high)
{
mid=(low+high)/2;
souce=0;
sink=2*n+1;
nv=sink+1;
memset(head,-1,sizeof(head));
memset(hash1,0,sizeof(hash1));
cnt=0;
for(i=1;i<=n;i++)
{
add(souce,i,mid);
add(i+n,sink,mid);
}
for(i=1;i<=m;i++)
{
int u=chao[i].girl;
int v=chao[i].boy;
for(j=1;j<=n;j++)
{
if(find1(u)==find1(j)&&!hash1[j][v])
{
hash1[j][v]=1;
add(j,v+n,1);
}
}
}
x=isap(mid);
//printf("%d\n",x);
if(x>=n*mid)
{
low=mid+1;
ans=mid;
}
else
{
high=mid-1;
}
}
printf("%d\n",ans);
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

HDU 3081Marriage Match II(二分法+并检查集合+网络流量的最大流量)的更多相关文章

  1. HDU 1272 小希迷宫(并检查集合)

    意甲冠军:被判处无向图无环和连接无处不在 思考:并检查集合,trap 您可能有一个直接输入0 0 并且....合并的时候按某一个方向会爆栈,爆了好几次...下次考虑一下直接递归找祖先吧 #includ ...

  2. HDU 1198 Farm Irrigation (并检查集合 和 dfs两种实现)

    Farm Irrigation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. POJ--2391--Ombrophobic Bovines【分割点+Floyd+Dinic优化+二分法答案】最大网络流量

    联系:http://poj.org/problem?id=2391 题意:有f个草场,每一个草场当前有一定数目的牛在吃草,下雨时它能够让一定数量的牛在这里避雨,f个草场间有m条路连接,每头牛通过一条路 ...

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

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

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

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

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

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

  7. HDU 3081 Marriage Match II 二分 + 网络流

    Marriage Match II 题意:有n个男生,n个女生,现在有 f 条男生女生是朋友的关系, 现在有 m 条女生女生是朋友的关系, 朋友的朋友是朋友,现在进行 k 轮游戏,每轮游戏都要男生和女 ...

  8. Marriage Match II(二分+并查集+最大流,好题)

    Marriage Match II http://acm.hdu.edu.cn/showproblem.php?pid=3081 Time Limit: 2000/1000 MS (Java/Othe ...

  9. HDU3081:Marriage Match II (Floyd/并查集+二分图匹配/最大流(+二分))

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

随机推荐

  1. hdu2208之搜索

    唉,可爱的小朋友 Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. GridBagLayout练习

    摘自http://blog.csdn.net/qq_18989901/article/details/52403737  GridBagLayout的用法 GridBagLayout是面板设计中最复杂 ...

  3. 国际C语言混乱代码大赛代码赏析(一)【转】

    本文转载自:http://blog.csdn.net/ce123_zhouwei/article/details/9073869 国际C语言混乱代码大赛代码赏析(一) 近段时间在看<C专家编程& ...

  4. Unity扩展 四种Menu的区别

    [MenuItem("Tools\AddColor")] :  在Unity菜单中添加一种快捷,执行public static方式 [AddComponentMenu(" ...

  5. IOS 计算密码强度

    + (BOOL) judgeRange:(NSArray*)conditionArr Password:(NSString*)password { NSRange range; BOOL result ...

  6. Struts2(五)——核心拦截器

    Struts框架一共为我们提供了35个拦截器,其中默认的拦截器有18个,框架访问action的异常处理,配置信息处理,转发重定向选择,上传等等等等,都是这18个拦截器中设置的,起着非比寻常的作用.而这 ...

  7. iOS https认证 && SSL/TLS证书申请

    1.下面列出截止2016年底市面上常见的免费CA证书: 腾讯云SSL证书管理(赛门铁克TrustAsia DV SSL证书)阿里云云盾证书服务(赛门铁克DV SSL证书)百度云SSL证书服务Let's ...

  8. Unity3d修炼之路:载入一个预制体,然后为该对象加入组件,然后查找对象,得到组件。

    #pragma strict function Awake(){ //载入一个预制体 资源必须在 Resources目录下 Resources.LoadLoad(); //载入后 必须演示样例化 Ga ...

  9. Kolor Neutralhazer v1.0.2 (照片雾气模糊去除过滤器)+破解RI

    由于空气污染.阴霾几天越来越,根据照片始终是一个灰色,怎么做?有了这个插件.能够解除您的烦恼. Neutralhazer这是消除你的风景照片和雾气模糊的全景图的有效途径photoshop小工具. wa ...

  10. 【降维解法:最大字段和->最大子矩阵和->最终版最大子长方体和】【UVA10755】Garbage Heap

    突然感觉刷完这一套专题后 码力有了质的飞跃,fighting 努力会有结果! 最大字段和是一个很经典的问题 O(n)算法 而对于最大子矩阵和 可以思考一个这样的想法 枚举上下边界i,j把i到j这一段的 ...