给个地图有人和房子

保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价

问让人都住在房子里最小代价


显然是个带权二分图最大匹配

转化成以一个网络,规定w是容量,c是代价

1.S向人连边,w=1,c=0

2.房子向T连边,w=1,c=0

3.人向房子连边 w=1,c=距离

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define N 10000
#define INF 1000000000
using namespace std;
deque <int> q;
int head[N],lev[N],dist[N],n,m,ecnt=1,vis[N],S,T,ans,H,M;
char mp[110][110];
struct adj
{
int nxt,v,w,c;
}e[200*200];
int Abs(int x)
{return x>0?x:-x;}
struct coor
{
int x,y;
int operator - (const coor &a)const
{return Abs(x-a.x)+Abs(y-a.y);}
};
coor make(int x,int y)
{
coor ret;
ret.x=x,ret.y=y;
return ret;
}
vector <coor> house,man;
inline void add(int u,int v,int w,int c)
{
e[++ecnt].v=v,e[ecnt].w=w,e[ecnt].c=c,e[ecnt].nxt=head[u],head[u]=ecnt;
e[++ecnt].v=u,e[ecnt].w=0,e[ecnt].c=-c,e[ecnt].nxt=head[v],head[v]=ecnt;
}
inline int spfa(int s,int t)
{
int v;
memset(vis,0,sizeof(vis));
for (int i=s;i<=t;i++) dist[i]=INF;
dist[t]=0,vis[t]=1;
q.push_back(t);
while (!q.empty())
{
int u=q.front();q.pop_front();
for (int i=head[u];i;i=e[i].nxt)
if (e[i^1].w>0 && dist[v=e[i].v]>dist[u]-e[i].c)
{
dist[v]=dist[u]-e[i].c;
if (!vis[v])
{
vis[v]=1;
if (!q.empty() && dist[v]<dist[q.front()])
q.push_front(v);
else
q.push_back(v);
}
}
vis[u]=0;
}
return dist[s]<INF;
}
inline int dfs(int x,int flow)
{
if (x==T)
return vis[T]=1,flow;
int used=0,tmp,v;
vis[x]=1;
for (int i=head[x];i;i=e[i].nxt)
if (!vis[v=e[i].v] && e[i].w>0 && dist[x]-e[i].c==dist[v])
{
tmp=dfs(v,min(e[i].w,flow-used));
if (tmp>0)
ans+=tmp*e[i].c,e[i].w-=tmp,e[i^1].w+=tmp,used+=tmp;
if (used==flow) break;
}
return used;
}
inline int CostFlow()
{
int Flow=0;
while (spfa(S,T))
{
vis[T]=1;
while (vis[T])
{
memset(vis,0,sizeof(vis));
Flow+=dfs(S,INF);
}
}
return Flow;
}
void init()
{
memset(head,0,sizeof(head));
man.clear();
house.clear();
ans=M=H=0;
ecnt=1;
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n==0 && m==0) break;
init();
for (int i=1;i<=n;i++)
scanf("%s",mp[i]+1);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (mp[i][j]=='m')
man.push_back(make(i,j)),M++;
else if (mp[i][j]=='H')
house.push_back(make(i,j)),H++;
T=H+M+1;
for (int i=0;i<M;i++)
for (int j=0;j<H;j++)
add(i+1,M+j+1,1,man[i]-house[j]);
for (int i=1;i<=M;i++)
add(S,i,1,0);
for (int i=1;i<=H;i++)
add(M+i,T,1,0);
CostFlow();
printf("%d\n",ans);
} return 0;
}

POJ 2195 Going Home | 带权二分图匹配的更多相关文章

  1. POJ 2195 Going Home (带权二分图匹配)

    POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...

  2. 运动员最佳匹配问题 KM算法:带权二分图匹配

    题面: 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势. ...

  3. 费用流模板(带权二分图匹配)——hdu1533

    /* 带权二分图匹配 用费用流求,增加源点s 和 汇点t */ #include<bits/stdc++.h> using namespace std; #define maxn 1000 ...

  4. hdu5045:带权二分图匹配

    题目大意 : n个人 做m道题,其中 每连续的n道必须由不同的人做 已知第i人做出第j题的概率为pij,求最大期望 思路:考虑每连续的n道题 都要n个人来做,显然想到了带权的二分图匹配 然后就是套模板 ...

  5. Glorious Brilliance (最短路 + 带权二分图匹配)

    这是一道代码大题.一开始读错题意了,然后理解成直接看上去的那种相邻,然后想不通好久!!! 把不同联通的图分离出来,然后先预处理一下形成之后的相邻图的状态,然后根据01确定哪一些是需要更换状态的,然后建 ...

  6. [NOI2012]美食节——费用流(带权二分图匹配)+动态加边

    题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...

  7. [HAOI2008]移动玩具(状压&带权二分图)

    题目描述 • 一个 4 × 4 的 0/1 矩阵 • 每次可以交换相邻两个元素 • 求从初始状态到目标状态的最小交换次数 输入格式 前四行,每行一个长为 4 的 0/1 字符串,描述初始状态. 后四行 ...

  8. Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)

    Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配) Description 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的 ...

  9. KM(Kuhn-Munkres)算法求带权二分图的最佳匹配

    KM(Kuhn-Munkres)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...

随机推荐

  1. jquery ajax参数

    //默认请求参数 var _options = { url: null, // 请求连接地址 type: 'GET', // 请求类型(get,post) data: null, // post时请求 ...

  2. LVS+Keepalived-DR模式负载均衡高可用集群

    LVS+Keepalived DR模式负载均衡+高可用集群架构图 工作原理: Keepalived采用VRRP热备份协议实现Linux服务器的多机热备功能. VRRP,虚拟路由冗余协议,是针对路由器的 ...

  3. VM虚拟机里的Ubuntu系统怎么设置屏幕分辨率

    说白了就是安装VMWare tools工具,步骤如下: 1)在VMWare中启动ubuntu虚拟机 2)在VMWare中:右键单击启动虚拟机,点击[安装vmware tools] 3)在ubuntu中 ...

  4. SQLSERVER 数据库恢复挂起的解决办法

    如果你的数据库还处于挂起状态,请把我下面代码的test改为你的库名,然后执行完,刷新就正常了: USE masterGOALTER DATABASE test SET SINGLE_USERGOALT ...

  5. java实现 zip解压缩

    程序实现了ZIP压缩.共分为2部分 : 压缩(compression)与解压(decompression) 大致功能包括用了多态,递归等JAVA核心技术,可以对单个文件和任意级联文件夹进行压缩和解压. ...

  6. 分析setup/hold电气特性从D触发器内部结构角度

    上图是用与非门实现的D触发器的逻辑结构图,CP是时钟信号输入端,S和R分别是置位和清零信号,低有效; D是信号输入端,Q信号输出端; 这里先说一下D触发器实现的原理:(假设S和R信号均为高,不进行置位 ...

  7. eBay 表结构

    erp_ebay_list 建表语句 CREATE TABLE `erp_ebay_list` ( `id` ) NOT NULL AUTO_INCREMENT COMMENT '自增主键', `na ...

  8. 浅谈UWB(超宽带)室内定位技术(转载)

    技术背景 随着无线通信技术的发展和数据处理能力的提高,基于位置的服务成为最有前途的互联网业务之一.无论移动在室内还是室外环境下,快速准确地获得移动终端的位置信息和提供位置服务的需求变得日益迫切.通信和 ...

  9. C语言进阶——注释符号12

    注释可能大认为非常简单,但是注释其实在C语言中很关键,来看下面一段对话. ---学生: 老师,我觉得注释没有必要深究,因为很简单,对程序功能也没有影响. ---老师: 注释是C语言最重要的工具,我们先 ...

  10. 011---Djang的cookie和session

    -------------------------------------------------------------cookie与session------------------------- ...