POJ 2195 【二分图最佳匹配】.cpp
题意:
有 n 个房子和 n 个人
每个人走一个单元你就要付 1$
有什么办法可以让把所有人都分派到房子里 而花费最少
输入:
给出n m 表示该矩阵由n 行 m 列组成
然后给出一个n*m的图
. 表示空地 H 表示房子 m 表示人
思路:
二分图最佳匹配<有权还要完全匹配>
Tips:
建图很有趣~
Code:
1 #include <stdio.h> 2 #include <cstring> 3 #include <cmath> 4 #define M 110 5 #define inf 0x1f1f1f1f 6 7 struct Node 8 { 9 int x; 10 int y; 11 }man[110], home[110]; 12 13 int n,nx,ny; 14 int link[M],lx[M],ly[M],slack[M]; //lx,ly为顶标,nx,nx分别为x点集y点集的个数 15 int visx[M],visy[M],w[M][M]; 16 17 int DFS(int x) 18 { 19 visx[x] = 1; 20 for (int y = 1;y <= nx;y ++) 21 { 22 if (visy[y]) 23 continue; 24 int t = lx[x] + ly[y] - w[x][y]; 25 if (t == 0) // 26 { 27 visy[y] = 1; 28 if (link[y] == -1||DFS(link[y])) 29 { 30 link[y] = x; 31 return 1; 32 } 33 } 34 else if (slack[y] > t) //不在相等子图中slack 取最小的 35 slack[y] = t; 36 } 37 return 0; 38 } 39 int KM() 40 { 41 int i,j; 42 memset (link,-1,sizeof(link)); 43 memset (ly,0,sizeof(ly)); 44 for (i = 1;i <= nx;i ++) //lx初始化为与它关联边中最大的 45 for (j = 1,lx[i] = -inf;j <= nx;j ++) 46 if (w[i][j] > lx[i]) 47 lx[i] = w[i][j]; 48 49 for (int x = 1;x <= nx;x ++) 50 { 51 for (i = 1;i <= nx;i ++) 52 slack[i] = inf; 53 while (1) 54 { 55 memset (visx,0,sizeof(visx)); 56 memset (visy,0,sizeof(visy)); 57 if (DFS(x)) //若成功(找到了增广轨),则该点增广完成,进入下一个点的增广 58 break; //若失败(没有找到增广轨),则需要改变一些点的标号,使得图中可行边的数量增加。 59 //方法为:将所有在增广轨中(就是在增广过程中遍历到)的X方点的标号全部减去一个常数d, 60 //所有在增广轨中的Y方点的标号全部加上一个常数d 61 int d = inf; 62 for (i = 1;i <= nx;i ++) 63 if (!visy[i]&&d > slack[i]) 64 d = slack[i]; 65 for (i = 1;i <= nx;i ++) 66 if (visx[i]) 67 lx[i] -= d; 68 for (i = 1;i <= nx;i ++) //修改顶标后,要把所有不在交错树中的Y顶点的slack值都减去d 69 if (visy[i]) 70 ly[i] += d; 71 else 72 slack[i] -= d; 73 } 74 } 75 int res = 0; 76 for (i = 1;i <= nx;i ++) 77 if (link[i] > -1) 78 res += w[link[i]][i]; 79 return -res; 80 } 81 82 int main () 83 { 84 int i, j, k; 85 int m; 86 char G[110][110]; 87 while (scanf("%d %d", &n, &m)!=EOF) 88 { 89 if(n == 0 && m == 0) break; 90 nx = 1, ny = 1; 91 // memset (w,0,sizeof(w)); 92 getchar(); 93 for(i = 0; i < n; ++i) 94 gets(G[i]); 95 96 for(i = 0; i < n; ++i) 97 for(j = 0; j < m; ++j) { 98 if(G[i][j] == 'm') { 99 man[nx].x = i; 100 man[nx++].y = j; 101 } 102 else if(G[i][j] == 'H') { 103 home[ny].x = i; 104 home[ny++].y = j; 105 } 106 } 107 108 for(i = 1; i < nx; ++i) 109 for(j = 1; j < ny; ++j) { 110 w[i][j] = -fabs(man[i].x - home[j].x) - fabs(man[i].y - home[j].y); 111 } 112 113 nx--; 114 int ans = KM(); 115 printf ("%d\n",ans); 116 } 117 return 0; 118 }
题目链接:http://poj.org/problem?id=2195
转载于:https://www.cnblogs.com/Griselda/archive/2012/09/28/2706534.html
POJ 2195 【二分图最佳匹配】.cpp相关推荐
- HDU - 奔小康赚大钱(二分图最佳匹配+KM)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...
- POJ365Ants_二分图最佳匹配
https://blog.csdn.net/lianai911/article/details/44835659 题意: 在坐标系中有N只蚂蚁,N棵苹果树,给你蚂蚁和苹果树的坐标.让每只蚂蚁去一棵苹果 ...
- 二分图最佳匹配 KM算法 Hdu2255奔小康赚大钱 + Poj 3565 Ants
2014-10-4 更新 在最下面增加了基于邻接表的模板 理论:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html http://philosci ...
- UVA-1045 - The Great Wall Game(二分图最佳匹配)
题意:在一个n*n的棋盘上有n个棋子,要求通过移动棋子使棋子的排布满足以下情况之一:呈横行排列:呈纵行排列:呈对角线排列(有两条). 棋子移动一个单元格的费用为1,总费用为所有棋子的移动费用之和.求最 ...
- 【二分图最佳匹配】丘比特的烦恼
丘比特的烦恼(Cupid.exe) 随着社会的不断发展,人与人之间的感情越来越功利化.最近,爱神丘比特发现,爱情也已不再是完全纯洁的了.这使得丘比特很是苦恼,他越来越难找到合适的男女,并向他们射去丘比 ...
- UVALive - 3353 Optimal Bus Route Design(二分图最佳匹配)
题目大意:给出一个n个点的有向带权图,找若干个圈,使得每个节点恰好属于一个圈,要求总长度尽量小 解题思路:首先要在一个圈内,且只能在一个圈内,那么每个点的入度和出度要都为1,所以二分图就有了 接着连边 ...
- HDU 2255 二分图最佳匹配 模板题
题目大意: 给定每一个人能支付的房子价值,每个人最多且必须拥有一套房子,问最后分配房子可得到的最大收益 抄了个别人的KM模板,就这样了... 1 #include <cstdio> 2 # ...
- KM算法 最优匹配(最大权匹配) hdu 2255 奔小康赚大钱 最小权匹配 poj 2195 Going Home
最大权二分匹配问题就是给二分图的每条边一个权值,选择若干不相交的边,得到的总权值最大.解决这个问题可以用KM算法.理解KM算法需要首先理解"可行顶标"的概念.可行顶标是指关于二分图 ...
- UVA - 1045 The Great Wall Game(二分图最佳完美匹配)
题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...
最新文章
- 集成Lua到你的Android游戏(常见问题补充,解决,)
- java 无法找到ant_无法找到与ANT(mac)关联的文件
- android控制音量加减命令 python_盘点5种基于Python生成的个性化语音方法
- matlab的数值计算功能,MATlAB数值计算功能
- MySQL利用存储过程清除所有表中的所有记录
- c语言编程输出所有水仙花数,c语言中,如何输出所有的水仙花数
- C:C++ 函数返回多个参数
- VMware安装Linux(CentOS7)
- 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程
- 声艺数字调音台si说明书32路_Soundcraft 声艺 Si Impact 数字调音台 32路数字调音台...
- 传感器的原理及应用有哪些
- Android蓝牙源码分析——BTA层消息分发
- 文本预处理:词袋模型(bag of words,BOW)、TF-IDF
- 【论文浅读】《Deep Pyramidal Residual Networks for Spectral–Spatial Hyperspectral Image Classification》
- 周杰:推荐只是一个新的信息的传播方式
- 谈谈keep-alive的理解
- 为什么Windows Mobile会失败?
- 华为P20 如时升Android 9.0,华为P20系列升级EMUI9.0之后简直太流畅太完美!
- uniapp拍卖商城源码功能解说
- 2021年全国大学生软件测试大赛web应用测试预选赛试题及答案
热门文章
- 样本量很少如何获得最佳的效果?最新小样本学习工具包来啦!
- 竞赛推荐:openEuler 高校开发者大赛启动!
- Mobile-LPR——面向移动端的准商业级车牌识别库
- 美国防部DARPA发起地下空间挑战赛提供3百万美元巨奖
- matlab 等势面立体图,求助大牛MATLAB画三维等势面
- 如何在windows上搭建mysql_如何在Windows上安装多个MySQL
- 【Python】Python实战从入门到精通之五 -- 教你使用文件写入
- python爬虫学习:电商数据分析
- python工程师工资状况_【python工程师工资|python工程师待遇怎么样】-看准网
- Centos7 下部署yapi 详细教程