职务地址: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. linux 有名管道(FIFO)

    http://blog.csdn.net/firefoxbug/article/details/8137762 linux 有名管道(FIFO) 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时 ...

  2. Keepalived+Lvs+Mysql主主复制

    一简单介绍 Keepalived+lvs+mysql主主复制是比較经常使用的一种Mysql高可用方案,当中lvs 提供读负载均衡,Keepalived通过虚拟vip漂移实现故障自己主动转移,而Mysq ...

  3. php 中利用json_encode和json_decode传递包括特殊字符的数据

    </pre><span style="font-size:24px"></span><pre name="code" ...

  4. Web Service中的XFire 传输List 自定义对象.

    我把这个创建的步骤和代码的贴出来,. 首先新建一个工程,取名就随便点啦..MyWebService,然后复制jar包到lib目录下, 创建包,建立接口..写一个javaBean的类, 以下是一个简单的 ...

  5. cocos2d-x(quick-lua)读取csv文件

    一.准备一份csv文件 ID,Name,Des,Model ID,名字,描写叙述,图片模型 1,广告,www.benmutou.com,csv.png 2,否认,呵呵,广告什么的,我才不会加,good ...

  6. 【贪心】【HDU3177】 搬家问题

    </pre><pre name="code" class="cpp">#include <iostream> #includ ...

  7. apache 开启压缩功能

    apache如何开启压缩功能. 1,首先先确认是安装deflatte模块.如果未安装,可以重新编译apache添加参数--enable-deflate=shared ,或者扩展安装deflate模块, ...

  8. TS相关知识点

    数字电视的TS包和TS流的组成和功能 综合考虑几下几个因素: (1)包的长度不能过短,否则包头开销所占比例过大, 导致传输效率下降 (2)包的长度不能过长,否则在丢失同步的情况下恢复同步的 周期过长, ...

  9. 一、MP3文件概述

    一.概述 MP3 文件是由帧(frame)构成的,帧是 MP3 文件最小的组成单位.MP3 的全称应为 MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts G ...

  10. .net如何后台批量删除

    button_Click(Sender sender,Event e){foreach (DataListItem item in DataList1.Items){CheckBox cbox=(Ch ...