月老的难题

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。

现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。

现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。

假设男孩们分别编号为1~n,女孩们也分别编号为1~n。

输入
第一行是一个整数T,表示测试数据的组数(1<=T<=400)
每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n。(n<=500,K<=10 000)
随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n)
输出
对每组测试数据,输出最多可能促成的幸福家庭数量
样例输入
1
3 4
1 1
1 3
2 2
3 2
样例输出
2

思路:

此题是经典的二分图匹配模板题,学习网络流后发现也可解(只需加一个超级源点和超级汇点,就变成了网路流的模板题)。刚好初学这两种算法,便将此题作为模板题整理下来;二分图匈牙利算法与网络流的Dinic算法耗时相当,但网络流(使用邻接表建图)的空间消耗较大;

二分图匹配—匈牙利算法, 资料:http://kukumayas.iteye.com/blog/1075610

http://blog.csdn.net/niushuai666/article/details/7023101

匈牙利算法代码:

#include <stdio.h>
#include <string.h>
#include <vector>
#define N 520using namespace std;int P_Num;                 // 人数
vector<int>Boy[N];            // 临界表,保存匹配信息
bool use[N];                // 标记数组
int form[N];                // 父节点(i号女生对应的男生编号) bool Match(int cur){                                      // 匹配函数 for(int i = 0; i < Boy[cur].size(); i ++){                // 遍历所有能与cur男生匹配的女生 if(!use[ Boy[cur].at(i) ]){                         // 判断该女生结点是否被判断过,没有进入 use[ Boy[cur].at(i) ] = 1;                       // 标记该女生已经判断 if(form[ Boy[cur].at(i) ] == -1 || Match(form[ Boy[cur].at(i) ])){       // 如果该女生未被匹配,或者之前匹配该女生的男生可以匹配其它女生 form[ Boy[cur].at(i) ] = cur;             // 则将该女生匹配给cur男生return 1;                                   // 成功匹配返回1 }}}return 0;
}int Hungary(){                                 // 匈牙利算法 int count = 0;                                // 计数器 memset(form, -1, sizeof(form));              // form保存女生对应的男生的编号,初始化为-1 for(int i = 1; i <= P_Num; i ++){          // 遍历每个男生结点,与女生深搜匹配 memset(use, 0, sizeof(use));         // 匹配前先将标记数组清零,起作用是防止重复搜索某结点 count += Match(i);}return count;
}int main()
{int loop, G_Num;scanf("%d", &loop);while(loop --){int start, end;scanf("%d%d", &P_Num, &G_Num);for(int i = 1; i <= P_Num; i ++){            // 多组数据初始化,清空数组 Boy[i].clear();}for(int i = 0; i < G_Num; i ++){scanf("%d%d", &start, &end);Boy[start].push_back(end);}int ans = Hungary();printf("%d\n", ans);}return 0;
}

网络流代码:

#include <stdio.h>
#include <string.h>
#include <queue>
#define INF 0x7fffffff
#define N 1020using namespace std;struct Node{int to;int weight;int next;
};Node edge[N * 100];
int head[N];
int level[N];
int edge_n;int min(int a, int b)
{return a < b ? a : b;
}void AddEdge(int start, int end, int weight)
{edge[edge_n].to = end;edge[edge_n].weight = weight;edge[edge_n].next = head[start];head[start] = edge_n ++;edge[edge_n].to = start;edge[edge_n].weight = 0;edge[edge_n].next = head[end];head[end] = edge_n ++;
}bool bfs(int start, int end)
{memset(level, 0, sizeof(level));queue<int>q;q.push(start);level[start] = 1;int cur;while(!q.empty()){cur = q.front();q.pop();for(int i = head[cur]; i != -1; i = edge[i].next){int v = edge[i].to;int w = edge[i].weight;if(w > 0 && !level[v]){level[v] = level[cur] + 1;if(v == end){return 1;}q.push(v);}}}return 0;
}int dfs(int cur, int end, int cp)
{if(cur == end){return cp;}int t, tmp = cp;for(int i = head[cur]; i != -1 && tmp; i = edge[i].next){int v = edge[i].to;int w = edge[i].weight;if(level[v] == level[cur] + 1 && w > 0){t = dfs(v, end, min(tmp, w));edge[i].weight -= t;edge[i ^ 1].weight += t;tmp -= t;}}return cp - tmp;
}int Dinic(int start, int end)
{int ans = 0, min_w;while( bfs(start, end) ){while( min_w = dfs(start, end, INF) ){ans += min_w;}}return ans;
}int main()
{int loop, ans;int p_num, ct;           // 男女人数,关系数目int boy_i, girl_i;scanf("%d", &loop);while(loop --){edge_n = 0;memset(head, -1, sizeof(head));scanf("%d%d", &p_num, &ct);while(ct --){                      // 建图scanf("%d%d", &boy_i, &girl_i);AddEdge(boy_i, girl_i + p_num, 1);}int src = 0, des = p_num * 2 + 1;  // 超级源点,超级汇点for(int i = 1; i <= p_num; i ++){AddEdge(src, i, 1);AddEdge(i + p_num, des, 1);}ans = Dinic(src, des);printf("%d\n", ans);}return 0;
}

nyoj-239 月老的难题 (二分图匹配—匈牙利算法 网络流—Dinic算法)相关推荐

  1. NYOJ - 239 - 月老的难题 ( 二分图最大匹配 匈牙利算法 )

    描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭. 现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸 ...

  2. nyoj 239 月老的难题 【二分匹配之匈牙利】

    月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一 ...

  3. NYOJ——239月老的难题(二分图最大匹配)

    月老的难题 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一家, ...

  4. nyoj 239 月老的难题

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=239 简单的二分匹配,不过这道题很怪,矩阵就是tle,临界表200多,很无语. 以前做个, ...

  5. NYOJ 题目239 月老的难题 (二分图最大匹配-匈牙利算法模板)

    月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一 ...

  6. nyoj239 月老的难题 二分图 匈牙利算法

    月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一 ...

  7. 二分图匹配匈牙利算法DFS实现

    1 /*==================================================*\ 2 | 二分图匹配(匈牙利算法DFS 实现) 3 | INIT: g[][]邻接矩阵; ...

  8. 二分图匹配--匈牙利算法

    文章目录 二分图: 匹配 匈牙利算法 代码: 二分图: 二分图是一个无向图,点集分成子集X和Y,图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时(包括0),G就是一个二分图 ...

  9. BZOJ.3140.[HNOI2013]消毒(二分图匹配 匈牙利)

    题目链接 不难想到每次一定是切一片. 如果是平面,很容易想到直接做二分图匹配.对于3维的? 可以发现min(a,b,c)的最大值只有\(\sqrt[3]{n}≈17\),我们暴力枚举这一最小值代表的是 ...

最新文章

  1. 从Pix2Code到CycleGAN:2017年深度学习重大研究进展全解读
  2. 利用python+seleniumUI自动化登录获取cookie后再去测试接口,今天终于搞定了
  3. Android四大组件之——Activity的生命周期(图文详解)
  4. Android之属性动画初步
  5. 无代码时代来临,程序员如何保住饭碗?赶紧看一看!
  6. 五菱神车,昙花一现还是创造蓝海?
  7. 内河港口首次实现区块链无纸化进口放货
  8. 安装logstash5.4.1,并使用grok表达式收集nginx日志
  9. DOS命令taskkill
  10. docker registry push 覆盖_Maven一键部署Springboot到Docker仓库,为自动化做准备
  11. Java PC端微信、支付宝扫码支付(一)
  12. 操作系统——实验一(Linux基本操作)
  13. typora 主题下载及安装
  14. 定义复数java_java怎么定义复数?
  15. 电脑键盘部分按键失灵_笔记本键盘部分失灵怎么办,笔记本个别键失灵的处理方法...
  16. 移动端轮播图——网易云音乐手机端样式
  17. 办公室计算机打印机共享,如何将办公室的所有电脑共享一个打印机???
  18. c#加粗代码_C# 字体加粗按钮
  19. [USACO10HOL]赶小猪
  20. Unity动态构建Mesh来绘制任意多边形(雷达图效果)

热门文章

  1. 【UE4】导入FBX格式的模型至UE4
  2. DanmuVis: Visualizing Danmu Content Dynamics and AssociatedViewer Behaviors in Online Videos
  3. 矩阵转置算法 oracle,请编写程序fun,函数的功能是:实现B=A+Aˊ,即把矩阵A加上A的转置,存放在矩阵B中。计算结果在main函...
  4. DOM系列之排他思想
  5. sizeof(long)
  6. springcloud24:分布式事务 Seata处理分布式事务总结篇
  7. 01-计算机系统概述
  8. NEO改进协议提案9(NEP-9)
  9. 实现表格内容第一行居中,其他行与第一行左对齐
  10. 帝国时代3如何快速实现训练单位突破人口上限