一、题目

题目描述
给定一个 n × m n\times m n×m的矩阵,里面’m’表示人,'H’表示房间,房间数和人数相等,每个人需要住进一个房间,问最小的行走距离综合。
数据范围
1 ≤ n , m , s ≤ 100 1\leq n,m,s\leq 100 1≤n,m,s≤100, s s s为人数。

二、解法

费用流裸题,图是这样建的:

  • 每个人连原点,边权为 0 0 0,容量为 1 1 1。
  • 每个房间连汇点,边权为 0 0 0,容量为 1 1 1。
  • 每个人连每个房间,边权是曼哈顿距离,容量为 1 1 1。

建图很简单,第一次写费用流,就是先跑一遍 d i j k s t r a dijkstra dijkstra,记录下来最短路径,然后增广这条路径,这里用的是 E K EK EK算法,但好像我写的 d i j k s t r a dijkstra dijkstra没有判负环,更像堆优化的 s p f a spfa spfa吧。

#include <cstdio>
#include <cstring>
#include <queue>
#define inf 0x3f3f3f3f
const int MAXN = 205;
using namespace std;
int read()
{int num=0,flag=1;char c;while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();return num*flag;
}
int n,m,k,tot,S,T,f[MAXN];
int dis[MAXN],pre[MAXN],lst[MAXN],flow[MAXN];
char a[105][105];
struct edge
{int v,f,c,next;
}e[MAXN*MAXN];
struct node
{int u,c;bool operator < (const node &R) const{return c>R.c;}
};
struct number
{int x,y,num;
};
priority_queue<node> q;
vector<number> A,B;
void add_edge(int u,int v,int c,int fl)
{e[++tot]=edge{v,fl,c,f[u]},f[u]=tot;e[++tot]=edge{u,0,-c,f[v]},f[v]=tot;
}
int Abs(int x)
{return x>0?x:-x;
}
int mht(int x1,int y1,int x2,int y2)
{return Abs(x1-x2)+Abs(y1-y2);
}
bool bfs()
{memset(dis,0x3f,sizeof dis);flow[S]=inf;dis[S]=0;pre[S]=-1;q.push(node{S,0});while(!q.empty()){int u=q.top().u,t=q.top().c;q.pop();if(dis[u]<t) continue;for(int i=f[u];i;i=e[i].next){int v=e[i].v,c=e[i].c;if(dis[v]>dis[u]+c && e[i].f>0){dis[v]=dis[u]+c;pre[v]=u;lst[v]=i;flow[v]=min(flow[u],e[i].f);q.push(node{v,dis[v]});}}}return dis[T]!=inf;
}
void get()
{int res=0,cost=0;while(bfs()){res+=flow[T];cost+=dis[T]*flow[T];int cur=T;while(cur!=S){e[lst[cur]].f-=flow[T];e[lst[cur]^1].f+=flow[T];cur=pre[cur];}}printf("%d\n",cost);
}
int main()
{while(~scanf("%d %d",&n,&m) && n && m){k=0;tot=1;A.clear();B.clear();for(int i=1;i<=n;i++){scanf("%s",a[i]+1);for(int j=1;j<=m;j++){if(a[i][j]=='m')A.push_back(number{i,j,++k});if(a[i][j]=='H')B.push_back(number{i,j,++k});}}S=0;T=k+1;for(int i=S;i<=T;i++)f[i]=0;for(int i=0;i<A.size();i++)add_edge(S,A[i].num,0,1);for(int i=0;i<B.size();i++)add_edge(B[i].num,T,0,1);for(int i=0;i<A.size();i++)for(int j=0;j<B.size();j++)add_edge(A[i].num,B[j].num,mht(A[i].x,A[i].y,B[j].x,B[j].y),1);get();}
}

HDU1533 Going Home相关推荐

  1. HDU1533(最小权完美匹配)

    题意:m表示人,H表示房子,一个人只能进一个房子,一个房子也只能进去一个人,房子数等于人数,现在要让所有人进入房子,求所有人都进房子最短的路径. 思路:平时使用都是最大权完美匹配,现在这道题要求最小权 ...

  2. HDU1533 Going Home(最小费用最大流 spfa模版)

    题意: 给你一个N行M列的矩阵,其中"."代表空地,"H"代表房子,"m"代表人,其中有n个房子和n个人.现在要求每个人进入一间房子,且人走 ...

  3. hdu1533解题报告

    题意:这里有一个N*M的方格图.....图中m代表人,H代表房子...并且人数和房子的数量是相等的..那么.每个人可以竖直或者横向走一格,并且花费1S元...那么为了让所有的人进入房子,求解最小的花费 ...

  4. HDU-1533(Going Home)

    题意:给你一个  的矩阵,矩阵中有数量相等皆为  的人和房子 ,房子不动,人只能往上下左右走,每走一步消耗 1 刀,现在要求每个人都走进一个房子,每个房子至多只能容纳一人,求最小消耗值: 分析:求二分 ...

  5. 最小费用最大流 HDU1533

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1533 #include<bits/stdc++.h> #define fi first ...

  6. Going Home HDU - 1533 (最小费用最大流)

    题目链接:https://cn.vjudge.net/problem/HDU-1533 题意:给你n个房子n个人  使得所有人都有一座房子的最小花费 思路:把所有的人与房子建边,最后,源点与所有的人建 ...

最新文章

  1. 枚举法用于逻辑问题的处理
  2. MyBatis关联查询,表字段相同,resultMap映射问题的解决办法
  3. 使用 DotNet CLI 创建自定义的 WPF 项目模板
  4. discuz程序的阅读(1)
  5. python零基础8分钟基础入门
  6. HDU1233 还是畅通工程
  7. 计算机中字符编码换算
  8. springboot testcontext @sql_举世闻名的 SQL 注入是什么?这个漫画告诉你!
  9. 益智棋类游戏--走四棋儿
  10. 2021软件测试、自动化测试、面试题整理
  11. 分享12个鲜为人知的的小众网站,每一个可以让你打开新世界的大门,让你震惊。...
  12. win10电脑插上U盘不显示盘符如何办?
  13. 2023秋招—大数据开发面经—蚂蚁金融
  14. IPAM——IP地址管理
  15. mac php pear pecl,MacOSX安装pecl - 米扑博客
  16. 胡说八道设计模式—观察者模式
  17. r语言 求几个数的最小公倍数_一课研究之“最小公倍数教学后学生知识技能情况分析”(20190417)...
  18. 大数据早报:百度开源移动端深度学习框架 中国联通成立大数据公司(9.26)
  19. 男人必学的几样家常炒菜,尤其是面对一个不会做饭的媳妇。
  20. 深入理解Lua的闭包:概念和应用

热门文章

  1. 路由器:简述对Routing路由表字段的认识
  2. 邮件服务器 sendmail发送附件
  3. 我的OpenCV细节笔记——VideoCapture打不开视频
  4. SurfaceFlinger原理(一):SurfaceFlinger的初始化
  5. (NO.00004)iOS实现打砖块游戏(十一):一闪一闪亮晶晶,我们都是小星星
  6. I服了U 报表软件等同于BI软件吗?
  7. 思维导图从入门到大神
  8. 无法定位序数 12384 于动态链接库 mfc90.dll
  9. 最好的MATLAB学习网站
  10. 电脑数据恢复软件有哪些,电脑数据恢复软件怎么用