POJ 2195 Going Home (最小费用最大流)

网友投稿 222 2022-08-30

POJ 2195 Going Home (最小费用最大流)

Description

Input

There are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M is the number of columns. The rest of the input will be N lines describing the map. You may assume both 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.

Output

For each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay.

Sample Input

2 2.mH.5 5HH..m...............mm..H7 8...H.......H.......H....mmmHmmmm...H.......H.......H....0 0

Sample Output

21028

题意

给出一张地图, ​​.​​​ 是空地, ​​H​​​ 是房子, ​​m​​ 是小人,并且地图上有相同数量的房子与小人,每个小人每次只能横向或者纵向移动一格,求最终所有人都找到一间独立的房子所走的步数。

思路

幸好地图上没有墙(降低难度),人物也可以相遇在同一格,那么小人距离任意一个房间的步数便是它们两者横坐标差+纵坐标差。

找一个源点,它与所有小人之见都有一条容量为1费用为0的边,然后所有房子与汇点之间也有一条容量为1费用为0的边,小人与房子之间的边容量为1,费用为它们之间的距离(步数)。

当然反向建图也可以,因为这张图是对称的嘛!并且房子个数与小人个数也相等。

然后求从源点到汇点之间的最小费用即可。

AC 代码

#include#include#include#include#include#includeusing namespace std;#include#includeconst int MAXX = 10005;const int INF = 0x3f3f3f3f;struct edge{ int to; //边终点 int next; //下一个兄弟位置 int cap; //容量 int flow; //流量 int cost; //费用} edge[MAXX<<2];int head[MAXX],tol;int pre[MAXX],dis[MAXX];int N; //节点总个数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++;}/* * SPFA 算法判断是否存在s到t的通路 */bool spfa(int s,int t){ queueq; bool vis[MAXX]; for(int i=0; iedge[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); } } } } return (pre[t]!=-1); //返回是否s到t是否有路径}/* * int s 起点 * int t 终点 */int minCostMaxFlow(int s,int t,int &cost){ int flow=0; while(spfa(s,t)) { int minn=INF; //当前路径可增广值 for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to]) //因为建图时每增加一条边会同时加入它的反向边,因此i^1为找出与i刚好相反的部分 { if(minn>edge[i].cap-edge[i].flow) minn=edge[i].cap-edge[i].flow; } for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to]) //修改图,计算花费 { edge[i].flow+=minn; edge[i^1].flow-=minn; cost+=edge[i].cost*minn; } flow+=minn; } return flow;}struct node{ int x; int y; node() {} node(int x,int y) { this->x=x; this->y=y; }};inline int getlen(node a,node b){ return abs(a.x-b.x)+abs(a.y-b.y);}int main(){ int n,m; char str[105][105]; while(~scanf("%d%d%*c",&n,&m)&&(n||m)) { node H[5005],M[5005]; //模拟栈 int th=0,tm=0; for(int i=0; i

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:HDU 4884 TIANKENG’s rice shop (模拟)
下一篇:上美集团一叶子“想桃就桃”刷屏的背后,关于内容营销的几点借鉴!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~