HDU 1533 KM算法(权值最小的最佳匹配)
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3299 Accepted Submission(s): 1674
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point. 
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 105
#define inf 999999999 int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int abs(int x,int y){return x<?-x:x;} struct KM {
int n, m;
int g[N][N];
int Lx[N], Ly[N], slack[N];
int left[N], right[N];
bool S[N], T[N]; void init(int n, int m) {
this->n = n;
this->m = m;
memset(g, , sizeof(g));
} void add_Edge(int u, int v, int val) {
g[u][v] += val;
} bool dfs(int i) {
S[i] = true;
for (int j = ; j < m; j++) {
if (T[j]) continue;
int tmp = Lx[i] + Ly[j] - g[i][j];
if (!tmp) {
T[j] = true;
if (left[j] == - || dfs(left[j])) {
left[j] = i;
right[i] = j;
return true;
}
} else slack[j] = min(slack[j], tmp);
}
return false;
} void update() {
int a = inf;
for (int i = ; i < m; i++)
if (!T[i]) a = min(a, slack[i]);
for (int i = ; i < n; i++)
if (S[i]) Lx[i] -= a;
for (int i = ; i < m; i++)
if (T[i]) Ly[i] += a;
} int km() {
memset(left, -, sizeof(left));
memset(right, -, sizeof(right));
memset(Ly, , sizeof(Ly));
for (int i = ; i < n; i++) {
Lx[i] = -inf;
for (int j = ; j < m; j++)
Lx[i] = max(Lx[i], g[i][j]);
}
for (int i = ; i < n; i++) {
for (int j = ; j < m; j++) slack[j] = inf;
while () {
memset(S, false, sizeof(S));
memset(T, false, sizeof(T));
if (dfs(i)) break;
else update();
}
}
int ans = ;
for (int i = ; i < n; i++) {
ans += g[i][right[i]];
}
return ans;
}
}kmm; int n, m;
char map[N][N];
int g[N][N]; struct node{
int x, y;
node(){}
node(int a,int b){
x=a;
y=b;
}
}a[N], b[N]; main()
{
int i, j, k;
int nx, ny;
while(scanf("%d %d",&n,&m)==){
if(n==&&m==) break; for(i=;i<n;i++) scanf("%s",map[i]);
nx=ny=;
memset(g,,sizeof(g));
for(i=;i<n;i++){
for(j=;j<m;j++){
if(map[i][j]=='m') a[nx++]=node(i,j);
if(map[i][j]=='H') b[ny++]=node(i,j);
}
}
kmm.init(nx,ny);
for(i=;i<nx;i++){
for(j=;j<ny;j++){
kmm.add_Edge(i,j,-(abs(a[i].x-b[j].x)+abs(a[i].y-b[j].y)));
}
}
printf("%d\n",-kmm.km());
}
}
HDU 1533 KM算法(权值最小的最佳匹配)的更多相关文章
- hdu Caocao's Bridges(无向图边双连通分量,找出权值最小的桥)
/* 题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同! tm太坑了... 1,如果这个无向图开始就是一个非连通图,直接输出0 2,重边(两个节点存在多条边, 权值不一样) 3,如果找到 ...
- hdu 3435(KM算法最优匹配)
A new Graph Game Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- UVA 548.Tree-fgets()函数读入字符串+二叉树(中序+后序遍历还原二叉树)+DFS or BFS(二叉树路径最小值并且相同路径值叶子节点权值最小)
Tree UVA - 548 题意就是多次读入两个序列,第一个是中序遍历的,第二个是后序遍历的.还原二叉树,然后从根节点走到叶子节点,找路径权值和最小的,如果有相同权值的就找叶子节点权值最小的. 最后 ...
- HDU 1533:Going Home(KM算法求二分图最小权匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=1533 Going Home Problem Description On a grid map there ...
- [ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- hdu 4862 KM算法 最小K路径覆盖的模型
http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...
- hdu 3488(KM算法||最小费用最大流)
Tour Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- HDU 2255 KM算法 二分图最大权值匹配
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
随机推荐
- JSP连接数据库的两种方式:Jdbc-Odbc桥和Jdbc直连(转)
学JSP的同学都要知道怎么连数据库,网上的示例各有各的做法,弄得都不知道用谁的好.其实方法千变万化,本质上就两种:Jdbc-Odbc桥和Jdbc直连. 下面先以MySQL为例说说这两种方式各是怎么连的 ...
- python中的for循环
打印出1到100的数,不包含100 for i in range(1,100): if i==23: print "great,you got your luncky number:&quo ...
- 分享几个Javascript 封装方法
基本封装方法 请看下面的例子: var Person = function(name,age){ this.name = name; this.age = age || "未填写" ...
- 【Todo】【转载】Spark学习 & 机器学习(实战部分)-监督学习、分类与回归
理论原理部分可以看这一篇:http://www.cnblogs.com/charlesblc/p/6109551.html 这里是实战部分.参考了 http://www.cnblogs.com/shi ...
- 转:c++内存分配
第一篇: http://my.oschina.net/pollybl1255/blog/140323 BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS ...
- 微信公共平台php用$GLOBALS["HTTP_RAW_POST_DATA"]收不到信息解决方法
http://www.cnblogs.com/shendiao/archive/2013/04/24/3041450.html <?php /** * wechat php test */ // ...
- Nodejs 配置+基础
Nodejs + NPP 配置. http://blog.csdn.net/foruok/article/details/48366765 NPM的全称是Node Package Manager,它就 ...
- OOAD与UML笔记
UML基础介绍 1.UML的定义 统一建模语言(UML)是一种图形化的语言,它可以帮助我们在OOAD过程中标识元素.构建模块.分析过程并可通过文档说明系统中的重要细节 2.OOAD OO ...
- 【bzoj1040】骑士
[bzoj1040]骑士 题意 给定一个基环森林,求最大独立集. 分析 其实这是一道一年前做过的题. 只是今天在看bzoj1023的时候突然来了几许兴致,回过头来看一看. 如果对于一棵树的最大独立集, ...
- 向html中添加节点
简单: ①,js中: (function () { var box=document.querySelector("#box"); var con1=document.create ...