首页 > 代码库 > poj 1274 The Perfect Stall 解题报告
poj 1274 The Perfect Stall 解题报告
题目链接:http://poj.org/problem?id=1274
题目意思:有 n 头牛,m个stall,每头牛有它钟爱的一些stall,也就是几头牛有可能会钟爱同一个stall,问牛与 stall 最大匹配数是多少。
二分图匹配,匈牙利算法入门题,留个纪念吧。
书上看到的一些比较有用的知识:
增广:通俗地说,设当前二分图中,已有 x 个匹配边(代码中match[i] 不为0的个数有x个),现在对 i 点(也就是代码中dfs中的参数 x) 指定一个匹配点 j, 由于 j 可能有匹配点设为 k,必须要为k找到一个新匹配 (对应黑屏中的前两次增广,本来的match[2] 从 1 变为 2 了,因为要为牛2找stall ,遇到map[2][2]边的时候发现match[2] 有数,只能调用dfs(match[2]) 为 match[2]找另一个匹配,也就是map[1][5],发现能找到,于是match[5] = 1,match[2] 就顺利成章变为2了)。
若能够找到,则表示匹配成功了x + 1 条边;若不能找到,相当于还是只有 x 个匹配边,只不过换了一种匹配方案而已,若达不到增加一条边的目的则称为对 i 增广不成功。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 6 using namespace std; 7 const int maxn = 200 + 5; 8 9 int map[maxn][maxn];10 int match[maxn]; // match[m]存储了匹配的方案, match[i] = j :仓库i里是牛j11 bool vis[maxn];12 int n, m, cnt;13 14 int dfs(int x) // 深搜找增广路径15 {16 for (int i = 1; i <= n; i++)17 {18 if (!vis[i] && map[x][i]) // 对x的每个邻接点19 {20 vis[i] = true;21 if (match[i] == 0 || dfs(match[i])) // 若 match[i] 点是一个初始值,表示i点原来没有匹配,则增广成功返回22 { // 或者 match[i]点能重新找到一个新的匹配点23 match[i] = x; // 保证新的匹配方案24 return 1;25 }26 }27 }28 return 0;29 }30 31 void Hungary()32 {33 cnt = 0;34 for (int i = 1; i <= n; i++) // 对 n 个点依次进行增广35 {36 memset(vis, 0, sizeof(vis));37 cnt += dfs(i); // 增广成功,表示i点找到了一个匹配,多了一条匹配边38 }39 }40 41 int main()42 {43 int k, to;44 while (scanf("%d%d", &n, &m) != EOF)45 {46 memset(map, 0, sizeof(map));47 memset(match, 0, sizeof(match));48 49 for (int i = 1; i <= n; i++)50 {51 scanf("%d", &k);52 for (int j = 1; j <= k; j++)53 {54 scanf("%d", &to);55 map[i][to] = 1;56 }57 }58 Hungary();59 printf("%d\n", cnt);60 }61 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。