Hdu1533带权二分图的最小匹配
来源:互联网 发布:人人贷网络借贷平台 编辑:程序博客网 时间:2024/06/04 19:53
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3961 Accepted Submission(s): 2036
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.
2 2.mH.5 5HH..m...............mm..H7 8...H.......H.......H....mmmHmmmm...H.......H.......H....0 0
21028
#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
const int MAXN=110;
const int inf=1<<30;
using namespace std;
char G[MAXN][MAXN];
int map[MAXN][MAXN];
int lx[MAXN],ly[MAXN];
int match[MAXN];
bool visitx[MAXN],visity[MAXN];
int n;
int Hungary(int u){
visitx[u]=true;
for(int i=0;i<n;i++){
if(!visity[i]&&lx[u]+ly[i]==map[u][i]){
visity[i]=true;
if(match[i]==-1||Hungary(match[i])){
match[i]=u;
return true;
}
}
}
return false;
}
void KM_prefect_match(){
int tmp;
//注意,此时要初始化为无穷小
for(int i=0;i<n;i++){
lx[i]=-inf;
}
memset(ly,0,sizeof(ly));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
lx[i]=max(lx[i],map[i][j]);
}
}
for(int i=0;i<n;i++)
{
while(1){
memset(visitx,false,sizeof(visitx));
memset(visity,false,sizeof(visity));
if(Hungary(i))//匹配成功
break;
else {
tmp=inf;
for(int j=0;j<n;j++)if(visitx[j]){//x在交错树中
for(int k=0;k<n;k++){
//y在交错树外
if(!visity[k]&&tmp>lx[j]+ly[k]-map[j][k]){
tmp=lx[j]+ly[k]-map[j][k];
}
}
}
//更新顶标
for(int j=0;j<n;j++){
if(visitx[j])
lx[j]-=tmp;
if(visity[j])
ly[j]+=tmp;
}
}
}
}
}
int main(){
int row,col;
while(~scanf("%d%d",&row,&col)){
if(row==0&&col==0)break;
n=0;
int cnt1=0,cnt2=0;
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
for(int i=0;i<row;i++){
scanf("%s",G[i]);
for(int j=0;j<col;j++){
if(G[i][j]=='m')n++;
}
}
//建图很重要!!!
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(G[i][j]=='m'){
for(int k=0;k<row;k++){
for(int l=0;l<col;l++){
if(G[k][l]=='H'){
map[cnt1][cnt2++]=-1*(abs(i-k)+abs(j-l));//由于求得是最小权值和,取相反数
}
}
}
cnt1++;
cnt2=0;
}
}
}
KM_prefect_match();
int ans=0;
for(int i=0;i<n;i++){
ans+=map[match[i]][i];
}
printf("%d\n",-ans);//最后取相反数就行了
}
return 0;
}
- Hdu1533带权二分图的最小匹配
- HDU1533/PKU2195 二分图匹配 费用流
- hdu1533 going home 二分图最优匹配
- 图论 二分图 hdu1533 KM最大匹配
- 堕落机房(带权二分图完美最小匹配)
- 二分图的最大带权匹配
- 二分图的最大带权匹配
- 带权的二分匹配
- HDU 1853 Cyclic Tour【最小费用最大流 OR 带权二分图匹配】
- 二分图的带权匹配和二分图的最优匹配
- poj2195 Going Home(二分图的最小权匹配)
- hdu 1533 Going Home 【最小权的二分图匹配】
- 二分图大讲堂——彻底搞定最大匹配数(最小覆盖数)、最大独立数、最小路径覆盖、带权最优匹配(二分图学习)
- 带权的二分图的最优匹配KM算法
- 带权二分图的最优匹配 Kuhn-Munkres算法
- HDU2255(带权二分图的最大匹配)
- 带权二分图的最优匹配 Kuhn-Munkres算法
- 带权二分图的最优匹配 Kuhn-Munkres算法
- 解析一个有关sizeof用法的题目--sizeof(i++)
- 应用程序无法正常启动(0xc000007b)
- CUDA编程(八)树状加法
- 二分 51Nod1686 第K大区间
- 害死人不偿命的(3n+1)猜想
- Hdu1533带权二分图的最小匹配
- 【开发环境问题】eclipse调试java web应用程序,应用程序奔溃
- 解决Android studio被依赖module里BuildConfig.DEBUG的值总为false问题
- 3D Touch 初试牛刀
- android activity之间传递对象(Serializable 和 Parcelable)
- FZU2101 大三的美好时光 【离散化+dp】
- 关于解决 MySQL 数据库主从复制延迟的问题
- 排序算法之堆排序
- C#中两个日期时间之间的时间间隔