题意

  求二分图最小完备匹配。

SOL

  建个图那么方便的事情是吧。。。然后边权都是正的(好像根边权也没什么关系),既然要求最小那么把边权取个相反数跑个KM就好了。。

CODE:

/*==========================================================================
# Last modified: 2016-02-16 19:55
# Filename: hdu1533.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
CODE:
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define lowbit(x) (x)&(-x)
#define INF 1070000000
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define maxn 200
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
/*==================split line==================*/ int n,sumx,sumy;
int w[maxn][maxn],link[maxn],lx[maxn],ly[maxn],slack[maxn],x[maxn],y[maxn];
bool S[maxn],T[maxn];
int calc(int i,int j){
int y1=x[i]%1000,x1=x[i]/1000,y2=y[j]%1000,x2=y[j]/1000;
return -(abs(y1-y2)+abs(x1-x2));
}
void build_graph(){
FORP(i,1,n)
FORP(j,1,n)
w[i][j]=calc(i,j);
}
bool match(int i){
S[i]=true;
FORP(j,1,n){
if (T[j]) continue;
int tmp=lx[i]+ly[j]-w[i][j];
if (tmp==0){
T[j]=true;
if (!link[j] || match(link[j])){
link[j]=i;
return true;
}
}
else slack[j]=min(slack[j],tmp);
}
return false;
}
void updata(){
int a=INF;
FORP(i,1,n) if (!T[i]) a=min(a,slack[i]);
FORP(i,1,n) {
if (S[i]) lx[i]-=a;
if (T[i]) ly[i]+=a;
else slack[i]-=a;
}
}
int KM(){ memset(link,0,sizeof(link));
memset(ly,0,sizeof(ly));
FORP(i,1,n)
FORP(j,1,n) lx[i]=max(lx[i],w[i][j]); FORP(i,1,n){
memset(slack,0x7f,sizeof(slack));
while (1){
memset(S,false,sizeof(S));
memset(T,false,sizeof(T));
if (match(i)) break;
else updata();
}
}
int ans=0;
FORP(i,1,n) if (link[i])
ans+=w[link[i]][i];
return -ans;
}
int main(){
//freopen("a.in","r",stdin);
int r,c;
while (1){
sumx=0; sumy=0;
scanf("%d%d",&r,&c);
if (r==0 && c==0) return 0;
FORP(i,1,r){
char ch[1000];
scanf("%s",ch);
FORP(j,0,c-1)
if (ch[j]=='m') x[++sumx]=i*1000+j+1;
else if (ch[j]=='H') y[++sumy]=i*1000+j+1;
}
n=sumx;
build_graph();
printf("%d\n",KM());
}
}

HDU 1533 & KM模板的更多相关文章

  1. HDU 2255 & KM模板

    题意: 一张完备二分图求最优完备匹配. SOL: 这题就不讲什么sol了...毕竟是裸的KM,不会的话可以看老人家的大白鼠,一些问题看代码注释.讲讲经历(悲惨的经历) 刚打完,自信地交上去发现MLE. ...

  2. HDU 1533 KM算法(权值最小的最佳匹配)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  3. hdu 1533 KM或费用流

    以前用KM写过,现在再用费用流写. #include <iostream> #include <cstdio> #include <cstring> #includ ...

  4. 【HDU 1533】 Going Home (KM)

    Going Home Problem Description On a grid map there are n little men and n houses. In each unit time, ...

  5. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

  6. HDU 1533 Going Home(KM完美匹配)

    HDU 1533 Going Home 题目链接 题意:就是一个H要相应一个m,使得总曼哈顿距离最小 思路:KM完美匹配,因为是要最小.所以边权建负数来处理就可以 代码: #include <c ...

  7. hdu 1686 KMP模板

    // hdu 1686 KMP模板 // 没啥好说的,KMP裸题,这里是MP模板 #include <cstdio> #include <iostream> #include ...

  8. HDU 2138 Miller-Rabin 模板题

    求素数个数. /** @Date : 2017-09-18 23:05:15 * @FileName: HDU 2138 miller-rabin 模板.cpp * @Platform: Window ...

  9. HDU 1533 最小费用最大流(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void ...

随机推荐

  1. ROS2.9.27架设网吧软路由实战篇之端口映射与回流

    转载:http://blog.csdn.net/zm2714/article/details/7924280 上一篇:ROS2.9.27架设网吧软路由实战篇之连通网络,主要讲述了网吧架设软路由ROS2 ...

  2. 【Hibernate】Hibernate系列3之配置文件详解

    配置文件详解 3.1.配置文件 连接池性能优化:http://www.cnblogs.com/xdp-gacl/p/4002804.html

  3. 【SpringMVC】SpringMVC系列14之SpringMVC国际化

    14.SpringMVC国际化 14.1.概述 14.2.用户切换选择语言

  4. TCP中 recv和sendf函数

    recv和send函数: #include<sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t nbytes, int fl ...

  5. Telegram

    官网:https://www.telegram.org/ GitHub:https://github.com/telegramdesktop/tdesktop

  6. 【JAVA、C++】LeetCode 017 Letter Combinations of a Phone Number

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  7. springMVC获取file,几种转换

    //从前台通过name值获取file MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)reque ...

  8. HDU 5793 A Boring Question (逆元+快速幂+费马小定理) ---2016杭电多校联合第六场

    A Boring Question Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. 转圈游戏(codevs 3285)

    题目描述 Description n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 ...

  10. cocos2dx实现象棋之运动

    1.头文件 void moveStone(int moveid, int killid, int x, int y); void moveComplete(CCNode*, void*); bool ...