On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel fee for every step he moves, until he enters 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.

InputThere 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. 
OutputFor each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay. 
Sample Input

  1. 2 2
  2. .m
  3. H.
  4. 5 5
  5. HH..m
  6. .....
  7. .....
  8. .....
  9. mm..H
  10. 7 8
  11. ...H....
  12. ...H....
  13. ...H....
  14. mmmHmmmm
  15. ...H....
  16. ...H....
  17. ...H....
  18. 0 0

Sample Output

  1. 2
  2. 10
  3. 28

题意:使得每个m都对应一个H时的最短的路径

题解:找一个源点,连接所有的m,再找一个汇点,使得所有H指向这个汇点。

然后跑一边最大费用最小流就ok了

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <queue>
  7. #include <cmath>
  8. using namespace std;
  9. typedef long long ll;
  10. const int MAXX=;
  11. const int INF=0x3f3f3f3f;
  12.  
  13. struct node
  14. {
  15. int st;
  16. int to;
  17. int next;
  18. int cap;
  19. int cost;
  20. }edge[MAXX];
  21.  
  22. char mp[][];
  23. int head[MAXX],tol;
  24. int pre[MAXX],dis[MAXX];
  25. bool vis[MAXX];
  26. int n,m,p;
  27.  
  28. struct node1
  29. {
  30. int x,y;
  31. node1(){}
  32. node1(int a,int b)
  33. {
  34. x=a;
  35. y=b;
  36. }
  37. };
  38. vector<node1> v1,v2;
  39.  
  40. void init()
  41. {
  42. tol=;
  43. memset(head,-,sizeof(head));
  44. v1.clear();
  45. v2.clear();
  46. }
  47.  
  48. void addedge(int u,int v,int cap,int cost)
  49. {
  50. edge[tol].st=u;
  51. edge[tol].to=v;
  52. edge[tol].cap=cap;
  53. edge[tol].cost=cost;
  54. edge[tol].next=head[u];
  55. head[u]=tol++;
  56.  
  57. edge[tol].st=v;
  58. edge[tol].to=u;
  59. edge[tol].cap=;
  60. edge[tol].cost=-cost;
  61. edge[tol].next=head[v];
  62. head[v]=tol++;
  63. }
  64.  
  65. bool SPFA(int s,int t)
  66. {
  67. queue<int> q;
  68. memset(dis,INF,sizeof(dis));
  69. memset(vis,,sizeof(vis));
  70. memset(pre,-,sizeof(pre));
  71. dis[s]=;
  72. vis[s]=;
  73. q.push(s);
  74. while(!q.empty())
  75. {
  76. int u=q.front(); q.pop();
  77. vis[u]=;
  78. for(int i=head[u];i!=-;i=edge[i].next)
  79. {
  80. int to=edge[i].to;
  81. if(edge[i].cap>&&dis[to]>dis[u]+edge[i].cost)
  82. {
  83. dis[to]=dis[u]+edge[i].cost;
  84. pre[to]=i;
  85. if(!vis[to])
  86. {
  87. vis[to]=;
  88. q.push(to);
  89. }
  90. }
  91. }
  92. }
  93. if(pre[t]==-)return ;
  94. return ;
  95. }
  96.  
  97. int minCostMaxFlow(int s,int t)
  98. {
  99. int cost=;
  100. while(SPFA(s,t))
  101. {
  102. int minn=INF;
  103. for(int i=pre[t];i!=-;i=pre[edge[i].st])
  104. minn=min(minn,edge[i].cap);
  105.  
  106. for(int i=pre[t];i!=-;i=pre[edge[i].st])
  107. {
  108. edge[i].cap-=minn;
  109. edge[i^].cap+=minn;
  110. }
  111. cost+=minn*dis[t];
  112. }
  113. return cost;
  114. }
  115.  
  116. int main()
  117. {
  118. while(scanf("%d%d",&n,&m)&&m&&n)
  119. {
  120. getchar();
  121. init();
  122. for(int i=;i<n;i++)
  123. {
  124. scanf("%s",mp[i]);
  125. getchar();
  126. }
  127. for(int i=;i<n;i++)
  128. for(int j=;j<m;j++)
  129. {
  130. if(mp[i][j]=='m')
  131. v1.push_back(node1(i,j));
  132. if(mp[i][j]=='H')
  133. v2.push_back(node1(i,j));
  134.  
  135. }
  136. int l=v1.size();
  137. int r=v2.size();
  138. for(int i=;i<v1.size();i++)
  139. {
  140.  
  141. node1 N1=v1[i];
  142. int x=i+;
  143. addedge(,x,,);
  144. for(int j=;j<v2.size();j++)
  145. {
  146. node1 N2=v2[j];
  147. int y=j+l+;
  148. int D=abs(N1.x-N2.x)+abs(N1.y-N2.y);
  149. addedge(x,y,,D);
  150. addedge(y,x,,D);
  151. if(i==l-)
  152. addedge(y,l+r+,,);
  153. }
  154. }
  155. int ans=minCostMaxFlow(,l++r);
  156. printf("%d\n",ans);
  157. }
  158. return ;
  159. }

Going Home HDU - 1533(最大费用最小流)的更多相关文章

  1. POJ 2195 & HDU 1533 Going Home(最小费用最大流)

    这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...

  2. POJ-2135-Farm Tour(最大费用最小流)模板

    Farm Tour POJ - 2135 When FJ's friends visit him on the farm, he likes to show them around. His farm ...

  3. 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 ...

  4. hdu 1533 Going Home 最小费用最大流 入门题

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  5. hdu 4322(最大费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4322 思路:建图真的是太巧妙了!直接copy大牛的了: 由于只要得到糖就肯定有1个快乐度,在这一点上糖 ...

  6. HDU 4322Candy 最大费用最大流

    由于被小孩子不喜欢的糖果的对小孩产生的效力是一样的,所以我们在网络流的时候先不考虑. 1 - 源点0到1~N个糖果,容量为1,费用为02 - 根据like数组,like[i][j] == 1时在糖果j ...

  7. hdu 1533 Going Home 最小费用最大流 (模板题)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. HDU 4406 最大费用最大流

    题意:现有m门课程需要复习,已知每门课程的基础分和学分,共有n天可以复习,每天分为k个时间段,每个时间段可以复习一门课程,并使这门课程的分数加一,问在不挂科的情况下最高的绩点. 思路:(没做过费用流的 ...

  9. 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

    题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. ...

随机推荐

  1. Android开发之利用SQLite进行数据存储

    Android开发之利用SQLite进行数据存储 Android开发之利用SQLite进行数据存储 SQLite数据库简单介绍 Android中怎样使用SQLite 1 创建SQLiteOpenHel ...

  2. layoutSubviews, setNeedsLayout, layoutIfNeeded

    layoutSubviews总结 ios layout机制相关方法 - (CGSize)sizeThatFits:(CGSize)size- (void)sizeToFit——————- - (voi ...

  3. Prevent the "split brain" by configuring the majority of nodes

    ## Prevent the "split brain" by configuring the majority of nodes (total number of nodes / ...

  4. Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图

    Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图 Bing Maps Silverlight Control虽然为我们提供了简洁.方面的开 ...

  5. C# 获得资源文件下图片的路径

    最终实现正确的代码是: button8.Image = System.Drawing.Image.FromFile(@"..\\..\\Resources\\GAOJIBAN.png&quo ...

  6. luogu 3796 【模板】AC自动机(加强版)

    我太菜了 棒神%%% #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib ...

  7. bzoj 1601 灌水

    题目大意: 决定把水灌到n块农田,农田被数字1到n标记 把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库 建造一个水库需要花费wi,连接两块土地需要花费Pij. 计算所需的最少代价 ...

  8. 根据JSON创建对应的HIVE表

    本文提供一种用SCALA把JSON串转换为HIVE表的方法,由于比较简单,只贴代码,不做解释.有问题可以留言探讨 package com.gabry.hiveimport org.json4s._im ...

  9. vue2.0 引入font-awesome

    网上的大部分教程复杂而且难看懂,其实两步就能搞定. 先cnpm install font-awesome --save引入依赖 然后在main.js引入 font-awesome/css/font-a ...

  10. 【转】Linux之printf命令

    转自:http://blog.chinaunix.net/uid-9525959-id-2001528.html printf FORMAT [ARGUMENT]... printf OPTION [ ...