题目大意:有一些男孩和女孩玩一个游戏,每个女孩都可以挑一个男孩来进行这个游戏(所有人都要参加),女孩只会挑选她喜欢的男孩,并且她们认为她们朋友喜欢的男孩她们也是喜欢的(朋友的男朋友也是我的男朋友???),而且她们遵循朋友的朋友也是朋友的原则,问她们最多可以玩几轮游戏(每轮要选择的人不能和以前选择的相同)。
 
分析:朋友关系很明显可以使用并查集找出来每个女孩可以连接的男孩,因为要求的是最多能进行多少轮游戏,也就是在这x轮游戏中每个女孩换了x不同的男孩,每个男孩也换了x个不同的女孩,如果源点和女孩相连,汇点和男孩相连,那么流量一定是N*x,可以使用二分来查找最大的x。
下面是AC代码。
=========================================================================================================================
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<vector>
using namespace std; const int MAXN = ;
const int oo = 1e9+; int G[MAXN][MAXN], Layer[MAXN], N, M;
int girl[MAXN*MAXN], boy[MAXN*MAXN], father[MAXN];
vector<int>love[MAXN]; int Find(int x)
{
if(father[x] != x)
father[x] = Find(father[x]);
return father[x];
}
void InIt()
{
for(int i=; i<=N; i++)
{
father[i] = i;
love[i].clear();
}
}
void BuidGraph(int flow, int start, int End)
{
memset(G, , sizeof(G)); for(int i=; i<=N; i++)
{///源点和女孩相连,汇点和男孩相连,流量是flow
G[start][i] = flow;
G[i+N][End] = flow; int u = Find(i);///注意别用father[i]
int len = love[u].size(); for(int j=; j<len; j++)
{///女孩和男孩之间的流量是1
G[i][love[u][j]] = ;
}
}
}
bool BFS(int start, int End)
{
memset(Layer, , sizeof(Layer));
queue<int> Q;
Q.push(start);
Layer[start] = ; while(Q.size())
{
int u = Q.front();Q.pop(); if(u == End)return true; for(int v=; v<=End; v++)
{
if(Layer[v]==false && G[u][v])
{
Layer[v] = Layer[u] + ;
Q.push(v);
}
}
} return false;
}
int DFS(int u, int MaxFlow, int End)
{
if(u == End)return MaxFlow; int uflow = ; for(int v=; v<=End; v++)
{
if(Layer[v]==Layer[u]+ && G[u][v])
{
int flow = min(MaxFlow-uflow, G[u][v]);
flow = DFS(v, flow, End); G[u][v] -= flow;
G[v][u] += flow;
uflow += flow; if(uflow == MaxFlow)
break;
}
} if(uflow == )
Layer[u] = ;
return uflow;
}
int Dinic(int start, int End)
{
int MaxFlow = ; while(BFS(start, End) == true)
MaxFlow += DFS(start, oo, End); return MaxFlow;
} int main()
{
int T; scanf("%d", &T); while(T--)
{
int i, F, u, v; scanf("%d%d%d", &N, &M, &F); InIt(); for(i=; i<=M; i++)
scanf("%d%d", &girl[i], &boy[i]);
for(i=; i<=F; i++)
{///用并查集合并朋友关系
scanf("%d%d", &u, &v);
u = Find(u);
v = Find(v); if(u != v)
father[u] = v;
} for(i=; i<=M; i++)
{///把相同的朋友的男朋友全部都连接到根节点上,男生的区间N~2*N
u = Find(girl[i]);
love[u].push_back(boy[i]+N);
} int start=N*+, End = start+;
int left = , right = N, ans=; while(left <= right)
{
int Mid = (left+right)>>; BuidGraph(Mid, start, End);
int MaxFlow = Dinic(start, End); if(MaxFlow == Mid*N)
{
left = Mid + ;
ans = Mid;
}
else
right = Mid - ;
} printf("%d\n", ans);
} return ;
}

N - Marriage Match II - HDU 3081(最大流)的更多相关文章

  1. Marriage Match II HDU - 3081(二分权值建边)

    题意: 有编号为1~n的女生和1~n的男生配对 首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 然后输入f组,c,d表示编号为c的女生和编号为d的女生是朋友 进行配对的要求满足其一即 ...

  2. 【HDU3081】Marriage Match II (二分+最大流)

    Description Presumably, you all have known the question of stable marriage match. A girl will choose ...

  3. hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //最大流的灵活运用

    3081 题意: n个女孩选择没有与自己吵过架的男孩有连边(自己的朋友也算,并查集处理),2分图,有些边,求有几种完美匹配(每次匹配每个点都不重复匹配) 我是建二分图后,每次增广一单位,(一次完美匹配 ...

  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 ...

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

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

  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. 转载:浅析C#深拷贝与浅拷贝

    原文地址 :http://www.cnblogs.com/xugang/archive/2010/09/09/1822555.html   感谢博主分享! 也许会有人这样解释C# 中浅拷贝与深拷贝区别 ...

  2. CSS before和after伪元素

    CSS中有一个特性允许我们添加额外元素而不扰乱文档本身,它们是以CSS选择器的形式出现的,具有标签的表现效果,但是呢又不是真正的标签元素,所以叫做“伪元素”.下面就说一下常见的两个伪元素before和 ...

  3. 程序里面的system.out.println()输出到其他位置,不输出到tomcat控制台。

    设置startup.bat: call "%EXECUTABLE%" run %CMD_LINE_ARGS% >> ..\logs\kongzitai.txt 将sys ...

  4. MySQL拷贝表的几种方式

    假如我们有以下这样一个表: id      username    password ----------------------------------- 1       admin       * ...

  5. ODAC的安装以及Entity Framework for Oracle 基本配置

    1.安装ODAC 根据自己操作系统x86,x64来判断下载的ODAC版本 http://www.oracle.com/technetwork/database/windows/downloads/ut ...

  6. cas sso单点登录系列3_cas-server端配置认证方式实践(数据源+自定义java类认证)

    转:http://blog.csdn.net/ae6623/article/details/8851801 本篇将讲解cas-server端的认证方式 1.最简单的认证,用户名和密码一致就登录成功 2 ...

  7. 装饰者模式(Decorator)

    首先来看一个例子: 比如,饮料可以分为很多种类,而这里我取一个咖啡,那么这个咖啡呢,有多种形式的, 比如有加糖了的咖啡,有加奶的咖啡,也有加热了的咖啡,也有加了冰块的咖啡. 而各个顾客的选择却是不同的 ...

  8. PHP Countable接口

    实现该接口可以使用count()方法来获取集合的总数

  9. C#实现的异步Socket服务器

    介绍 我最近需要为一个.net项目准备一个内部线程通信机制. 项目有多个使用ASP.NET,Windows 表单和控制台应用程序的服务器和客户端构成. 考虑到实现的可能性,我下定决心要使用原生的soc ...

  10. Java学习----main详解

    public class Test1 { public static void main(String[] args) { System.out.println("Hello"); ...