hdu 1533 Going Home 最小费用最大流 入门题
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3125 Accepted Submission(s): 1590
a house. The task is complicated with the restriction that each house can accommodate only one little man.
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.
N and M are between 2 and 100, inclusive. There will be the same number of 'H's and 'm's on the map; and there will be at most 100 houses. Input will terminate with 0 0 for N and M.
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
2 10 28
题意:把H和m一一配对。他们所需走的最小步数和 为多少。
做法:用bfs 先找出 随意 H 和 m 直接的最小步数。记录下来。 然后像二分图一样建图。 起点到 全部home 流量1,费用0。 home 和man 之间的费用为距离,流量1,man和终点ee之间流量1,费用0。 建图完。然后用最小费用最大流 跑一边就ok了。
- #include <cstdio>
- #include <iostream>
- #include <cmath>
- #include <cstring>
- #include <vector>
- #include <stdlib.h>
- #include <queue>
- #include <map>
- #include <algorithm>
- using namespace std;
- const int MAXN = 10100;
- const int MAXM = 30000000;
- const int INF = 0x3f3f3f3f;
- struct Edge
- {
- int to,next,cap,flow,cost;
- }edge[MAXM];
- int head[MAXN],tol;
- int pre[MAXN],dis[MAXN];
- bool vis[MAXN];
- int N;//节点总个数,节点编号从0~N-1
- void init(int n)
- {
- N = n;
- tol = 0;
- memset(head,-1,sizeof(head));
- }
- void addedge(int u,int v,int cap,int cost)
- {
- edge[tol].to = v;
- edge[tol].cap = cap;
- edge[tol].cost = cost;
- edge[tol].flow = 0;
- edge[tol].next = head[u];
- head[u] = tol++;
- edge[tol].to = u;
- edge[tol].cap = 0;
- edge[tol].cost = -cost;
- edge[tol].flow = 0;
- edge[tol].next = head[v];
- head[v] = tol++;
- }
- bool spfa(int s,int t)
- {
- queue<int>q;
- for(int i = 0;i < N;i++)
- {
- dis[i] = INF;
- vis[i] = false;
- pre[i] = -1;
- }
- dis[s] = 0;
- vis[s] = true;
- q.push(s);
- while(!q.empty())
- {
- int u = q.front();
- q.pop();
- vis[u] = false;
- for(int i = head[u]; i != -1;i = edge[i].next)
- {
- int v = edge[i].to;
- if(edge[i].cap > edge[i].flow &&
- dis[v] > dis[u] + edge[i].cost )
- {
- dis[v] = dis[u] + edge[i].cost;
- pre[v] = i;
- if(!vis[v])
- {
- vis[v] = true;
- q.push(v);
- }
- }
- }
- }
- if(pre[t] == -1)return false;
- else return true;
- }
- //返回的是最大流。 cost存的是最小费用
- int minCostMaxflow(int s,int t,int &cost)
- {
- int flow = 0;
- cost = 0;
- while(spfa(s,t))
- {
- int Min = INF;
- for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
- {
- if(Min > edge[i].cap - edge[i].flow)
- Min = edge[i].cap - edge[i].flow;
- }
- for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
- {
- edge[i].flow += Min;
- edge[i^1].flow -= Min;
- cost += edge[i].cost * Min;
- }
- flow += Min;
- }
- return flow;
- }
- int n,m;
- struct node
- {
- int x,y,bu;
- };
- //addedge(int u,int v,int cap,int cost)
- char mp[110][110];//地图
- char num[110][110];//点查 号
- int mp_dis[110][110];//号 号距离 前 home 后 men
- int mp_vis[110][110];
- int dir[4][2]={1,0,0,1,0,-1,-1,0};
- void bfs(int x,int y)
- {
- memset(mp_vis,-1,sizeof mp_vis);
- queue<node> q;
- node sta,nw,tem;
- sta.bu=0;
- sta.x=x;
- sta.y=y;
- q.push(sta);
- while(!q.empty())
- {
- nw=q.front();
- q.pop();
- if(mp[nw.x][nw.y]=='m')
- mp_dis[num[x][y]][num[nw.x][nw.y]]=nw.bu;
- for(int i=0;i<4;i++)
- {
- int xx=nw.x+dir[i][0];
- int yy=nw.y+dir[i][1];
- if(xx<0||xx>=n||yy<0||yy>=m)
- continue;
- if(mp_vis[xx][yy]!=-1&&nw.bu+1>=mp_vis[xx][yy])
- continue;
- tem.x=xx;
- tem.y=yy;
- mp_vis[xx][yy]=tem.bu=nw.bu+1;
- q.push(tem);
- }
- }
- }
- int main()
- {
- while(cin>>n>>m,n||m)
- {
- for(int i=0;i<n;i++)
- {
- scanf("%s",mp[i]);
- }
- int home,man;
- home=man=0;
- for(int i=0;i<n;i++)
- {
- for(int j=0;j<m;j++)
- {
- if(mp[i][j]=='H')
- num[i][j]=home++;
- if(mp[i][j]=='m')
- num[i][j]=man++;
- }
- }
- for(int i=0;i<n;i++)
- {
- for(int j=0;j<m;j++)
- {
- if(mp[i][j]=='H')
- bfs(i,j);
- }
- }
- int ss=home+man;
- int ee=home+man+1;
- init(home+man+2);
- for(int i=0;i<home;i++)
- {
- for(int j=0;j<man;j++)
- {
- addedge(i,home+j,1,mp_dis[i][j]);
- }
- }
- for(int i=0;i<home;i++)
- addedge(ss,i,1,0);
- for(int i=0;i<man;i++)
- addedge(home+i,ee,1,0);
- /*
- for(int i=0;i<n;i++)
- {
- for(int j=0;j<m;j++)
- {
- printf("%c%d ",mp[i][j],num[i][j]);
- }
- puts("");
- }
- for(int i=0;i<home;i++)
- {
- for(int j=0;j<man;j++)
- {
- printf("%d ",mp_dis[i][j]);
- }
- puts("");
- }
- */
- int ans;
- minCostMaxflow(ss,ee,ans);
- printf("%d\n",ans);
- }
- return 0;
- }
- /*
- 2 2
- .m
- H.
- 5 5
- HH..m
- .....
- .....
- .....
- mm..H
- 7 8
- ...H....
- ...H....
- ...H....
- mmmHmmmm
- ...H....
- ...H....
- ...H....
- 0 0
- */
hdu 1533 Going Home 最小费用最大流 入门题的更多相关文章
- hdu 1533 Going Home 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n house ...
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...
- POJ 2135 最小费用最大流 入门题
Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19207 Accepted: 7441 Descri ...
- hdu 1533 Going Home 最小费用最大流 (模板题)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 【网络流#2】hdu 1533 - 最小费用最大流模板题
最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...
- HDU 5988.Coding Contest 最小费用最大流
Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 3667(拆边+最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667 思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式. ...
- hdu 3488(KM算法||最小费用最大流)
Tour Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
随机推荐
- 洛谷 P1604 B进制星球
P1604 B进制星球 题目背景 进制题目,而且还是个计算器~~ 题目描述 话说有一天,小Z乘坐宇宙飞船,飞到一个美丽的星球.因为历史的原因,科技在这个美丽的星球上并不很发达,星球上人们普遍采用B(2 ...
- CsGL着色的三角形
转自NeHe教程 public override void Draw() { // Here's Where We Do All The Drawing glClear(GL_COLOR_BUFFER ...
- ArcSDE学习笔记---------使用
1.首先在 将下面四个jar包放到工程里 2.然后打开ArcMAP,在arcmap里建立属于你自己的表 3.然后在你的本地数据库上建立与arcmap的连接 完成这三步就可以开始对ArcSDE的数据进行 ...
- SICP 习题 (2.11)解题总结:区间乘法的优化
SICP 习题 2.11又出现Ben这个人了,如曾经说到的,仅仅要是Ben说的一般都是对的. 来看看Ben说什么.他说:"通过监測区间的端点,有可能将mul-interval分解为9中情况, ...
- 最全Pycharm教程(10)——Pycharm调试器总篇
最全Pycharm教程(1)--定制外观 最全Pycharm教程(2)--代码风格 最全Pycharm教程(3)--代码的调试.执行 最全Pycharm教程(4)--有关Python解释器的相关配置 ...
- nginx假死导致的问题回顾
背景: 网络大致拓扑型 定位到一台Nginx节点于凌晨Timewait异常,等到6K. 进程异常,ngx_http_realtime_request模块错误 错误日志: 2017/02/24 00:0 ...
- C/C++(C++返回对象与应用区别,类成员的存储)
返回对象与应用区别: 拷贝构造器发生的时机: 1.构造新对象 A a, A b = a; 2.传参或返回对象 对于普通变量来说,传引用效果不是很明显,对于类对象而言,传对象效果很高. 传引用等价于扩大 ...
- linux下pptp配置步骤
最近买了个VPS,于是随手搭了个VPN玩,ubuntu安装pptp太蠢了,直接apt-install pptp就行了 1./etc/pptpd.conf 注销最后两行,就是设置IP转发的范围,给那么几 ...
- secureCRT 小技巧
破解: keygen.exe 放到安装目录下填好姓名公司 ,patch后generate就行了 连接问题: 连接出现socket error很有可能是你的防火墙没关,今天排查了很久才发现是这个问题,浪 ...
- javaScript 立即执行函数学习笔记
立即执行函数: 即执行函数(Immediate Functions),立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行 立即执行函数(immediate function)术语不是在ECM ...