HDU 2255 — 奔小康赚大钱 KM入门题
2015-08-02 16:38
183 查看
原题:http://acm.hdu.edu.cn/showproblem.php?pid=2255
#include<stdio.h> #include<string.h> #include<algorithm> #define inf 1e9 using namespace std; const int maxn = 310; int nx, ny; //nx、ny分别表示X集和Y集的顶点数; int match[maxn]; int lx[maxn], ly[maxn], slack[maxn], w[maxn][maxn]; //lx、ly分别为X集和Y集的顶标; bool visx[maxn], visy[maxn]; bool dfs(int x) { visx[x] = true; for(int y = 1;y<=ny;y++) { if(visy[y]) continue; int t = lx[x]+ly[y]-w[x][y]; if(t == 0) { visy[y] = true; if(match[y] == 0 || dfs(match[y])) { match[y] = x; return true; } } else if(slack[y]>t) slack[y] = t; } return false; } int KM() { memset(ly, 0, sizeof ly); memset(match, 0, sizeof match); for(int i = 1;i<=nx;i++) //将lx初始化为与它关联的边中权值最大的; { lx[i] = -inf; for(int j = 1;j<=ny;j++) lx[i] = max(lx[i], w[i][j]); } for(int x = 1;x<=nx;x++) { for(int y = 1;y<=ny;y++) slack[y] = inf; while(1) { memset(visx, false, sizeof visx); memset(visy, false, sizeof visy); if(dfs(x)) //如果成功,则表示找到了增广轨,该点增广完成,就可以寻找下一个点的增广轨; break; //如果失败,则需要改变一些点的标号,增加可行边; int d = inf; for(int i = 1;i<=ny;i++) { if(!visy[i]) d = min(d, slack[i]); } for(int i = 1;i<=nx;i++) { if(visx[i]) lx[i]-=d; } for(int i = 1;i<=ny;i++) { if(visy[i]) ly[i]+=d; else slack[i]-=d; } } } int res = 0; for(int i = 1;i<=ny;i++) { if(match[i]) res+=w[match[i]][i]; } return res; } int main() { int n; while(scanf("%d", &n)!=EOF) { nx = ny = n; for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++) scanf("%d", &w[i][j]); int ans = KM(); printf("%d\n", ans); } return 0; }
相关文章推荐
- 服务层的必要性
- TCP建立连接和释放的过程,及TCP状态变迁图
- 第一篇博文:PHP函数原型中的可选参数写法为什么这么写?
- 用python加cPAMIE加pyinstaller为我柱哥点赞
- 【leetcode】Implement Queue using Stacks
- leetcode 抢房子House Robber
- C语言编程入门——指针(上)
- Excel数据导入导出
- 点分治小结
- tomcat发布后,没有class文件,只有项目目录和properties,xml之类的文件解决办法
- NIM 博弈
- 华为是怎样研发的(10)——知识管理
- oracle 取左表不在右表记录的3种方法-引申到db2-开发系列(五)
- 黑马程序员——Java学习笔记——数组的排序和查找
- 从多元方程组到矩阵计算的乘法法则
- 数据压缩与信息熵
- HDU 4746 Mophues 莫比乌斯第三弹
- iOS绘制效果界面
- My summery
- C++对象模型——Data 语意学(第三章)