题目链接:http://poj.org/problem?id=2195

题目大意是给一张网格,网格中m代表人,h代表房子,网格中的房子和人数量相等,人可以向上向下走,每走1步花费加1,每个房子只能住一个人,问使得所有人住房子里最少的花费是多少?

最小费用流的题目,最大流跑spfa,每个人和每个房子之间建边,边的流量为1,花费是人到房子的距离,假定一个源点和一个汇点,源点连接所有的人,每条边流量为1,花费为0,所有的房子连接汇点,同样的边流量是1,花费是0,从源点到汇点跑一下费用流就可以得出答案。其中每个人到每个房子的距离d = 纵坐标的差值绝对值+横坐标的差值绝对值。图很好建,细节注意一下,多组数据记得初始化。

AC代码:

  1. #include<iostream>
  2. #include<vector>
  3. #include<algorithm>
  4. #include<queue>
  5. using namespace std;
  6. #define inf 0x3f3f3f3f
  7. struct node{
  8. vector<int> vex;//g[i]连接的点集
  9. vector<int> num;//g[i]连接的边集
  10. }g[205];
  11. struct edge{
  12. int u,v,c,cost;//u起点,v终点,c流量 cost花费
  13. }e[205*205];
  14. vector<pair<int,int> > Vmen;//存储人的坐标
  15. vector<pair<int,int> > Vh;//存储房子的坐标
  16. int men = 0,h = 0;//人和房子的个数
  17. int sp,tp;//源点汇点
  18. int inq[205],d[205],pre[205];
  19. int cal(int a,int b){// a为人,b为房子 first横坐标,second纵坐标
  20. return abs(Vmen[a].first - Vh[b].first)+abs(Vmen[a].second - Vh[b].second);
  21. }
  22. int edgenum ;//边的序号从0开始,
  23. void addedge(int u,int v,int c,int cost){
  24. e[edgenum].u = u,e[edgenum].v = v;
  25. e[edgenum].c = c,e[edgenum].cost = cost;
  26. g[u].vex.push_back(v),g[u].num.push_back(edgenum++);
  27. // 建立双向边操作
  28. e[edgenum].u = v,e[edgenum].v = u;
  29. e[edgenum].c = 0,e[edgenum].cost = -cost;
  30. g[v].num.push_back(edgenum++),g[v].vex.push_back(u);
  31. }
  32. bool spfa(int s,int t){
  33. for(int i = 0;i<205;i++){
  34. inq[i] = 0;//是否在队列
  35. d[i] = inf;//记录最小花费
  36. pre[i] = -1;//初始化-1
  37. }//初始化
  38. d[s] = 0,inq[s] = 1;
  39. queue<int> q;
  40. q.push(s);
  41. while(!q.empty()){
  42. int now = q.front() ;
  43. q.pop() ;
  44. inq[now] = 0;
  45. for(int i = 0;i<g[now].num.size() ;i++ ){
  46. int te = g[now].num[i];
  47. int tv = g[now].vex[i];
  48. if(e[te].c >0 && d[tv] > d[now] + e[te].cost ){
  49. d[tv] = d[now] + e[te].cost ;
  50. pre[tv] = te;//存储以tv为后继节点的边集 该边te : now->tv
  51. if(!inq[tv]){
  52. inq[tv] = 1;
  53. q.push(tv);
  54. }
  55. }
  56. }
  57. }
  58. return d[tp]!=inf; //找不到增广路就返回false
  59. }
  60. int mincostmaxflow(int s,int t){
  61. int ans_cost = 0, u,minCut;
  62. while(spfa(s,t)){
  63. minCut = inf;
  64. for(u = pre[t];u!=-1;u = pre[e[u].u]){
  65. if(minCut > e[u].c ){
  66. minCut = e[u].c ;
  67. }
  68. }
  69. for(u = pre[t];u!=-1;u = pre[e[u].u]){
  70. e[u^1].c+=minCut;//双向边做加和该增广路最大流操作
  71. e[u].c-=minCut;
  72. }
  73. ans_cost+=minCut*d[tp];
  74. }
  75. return ans_cost;
  76. }
  77. vector<string> map;
  78. int main(){
  79. int n,m;
  80. while(cin>>n>>m){
  81. if(!n&&!m){
  82. return 0;
  83. }
  84. edgenum = 0,map.clear(),Vmen.clear(),Vh.clear(),men = 0,h = 0;//初始化数据
  85. for(int i = 0;i<205;i++){
  86. g[i].num.clear();
  87. g[i].vex.clear();
  88. }//初始化数据
  89. for(int i = 0;i<n;i++){
  90. string t;
  91. cin>>t;
  92. map.push_back(t);
  93. }
  94. for(int i = 0;i<map.size();i++){
  95. for(int j = 0;j<m;j++){
  96. if(map[i][j] == 'H'){
  97. h++;
  98. Vh.push_back(make_pair(i,j));
  99. }
  100. if(map[i][j] == 'm'){
  101. men++;
  102. Vmen.push_back(make_pair(i,j));
  103. }
  104. }
  105. }
  106. sp = 0;
  107. tp = men+h+1;
  108. for(int i = 1;i<=men;i++){
  109. addedge(sp,i,1,0);
  110. }
  111. for(int i = men+1;i<=2*men;i++){
  112. addedge(i,tp,1,0);
  113. }
  114. for(int i = 0;i<Vmen.size() ;i++){
  115. for(int j = 0;j<Vh.size() ;j++){
  116. int cost = cal(i,j);
  117. addedge(i+1,men+j+1,1,cost);
  118. }
  119. }
  120. cout<<mincostmaxflow(sp,tp)<<endl;
  121. }
  122. return 0;
  123. }

poj 2195 Going Home(最小费用流)的更多相关文章

  1. POJ 2195 Going Home 最小费用流 裸题

    给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数. 现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人. 每个人可以向4个方向移动,每移动一步需要1$,问所有 ...

  2. POJ 2195 Going Home 最小费用流 难度:1

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17955   Accepted: 9145 Descr ...

  3. POJ 2195 Going Home 最小费用流

    POJ2195 裸的最小费用流,当然也可以用KM算法解决,但是比较难写. 注意反向边的距离为正向边的相反数(因此要用SPFA) #include<iostream> #include< ...

  4. POJ 2195 Going Home 最小费用最大流 尼玛,心累

    D - Going Home Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  5. poj 2195 二分图带权匹配+最小费用最大流

    题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...

  6. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

  7. POJ 2195 Going Home (带权二分图匹配)

    POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...

  8. poj 2195 Going Home(最小费最大流)

    poj 2195 Going Home Description On a grid map there are n little men and n houses. In each unit time ...

  9. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

随机推荐

  1. 给静态网站的链接添加nofollow属性

    给网站的链接添加nofollow属性对SEO非常有效,如果是动态网站,实现的方法比较多,但是对于静态网站来说只能借助CSS或者JS来实现,单纯的CSS实现需要覆盖所有的链接出现位置:JS与CSS结合则 ...

  2. 为什么在linux系统下安装anaconda的时候会报错

    报错界面 一开始是在官网下载的最新的包,出现了上述的报错,但是换成清华镜像之后,就没有上述报错了? 我猜测可能是因为 官网最新的版本的anaconda和你安装的python版本不兼容,而在镜像上的不是 ...

  3. py 二级习题(turtle)

    用turtle画一个正方形 import turtle turtle.penup() turtle.goto(-100,-100) turtle.pendown() turtle.begin_fill ...

  4. 51 nod1067 Bash游戏 V2(sg函数打表)

    1067 Bash游戏 V2 1.0 秒 131,072.0 KB 5 分 1级题   有一堆石子共有N个.A B两个人轮流拿,A先拿.每次只能拿1,3,4颗,拿到最后1颗石子的人获胜.假设A B都非 ...

  5. 利用 Hexo + Github 搭建自己的博客

    扯在前面 在很久很久以前,一直就想搭建属于自己的一个博客,但由于各种原因,最终都不了了之,恰好最近突然有了兴趣,于是就自己参照网上的教程,搭建了属于自己的博客. 至于为什么要搭建自己的博客了?哈哈,大 ...

  6. 解决myeclipse2017ci7破解后闪退问题

    解决myeclipse2017ci7破解后闪退问题 打开myeclipse.ini修改为: #utf8 (do not remove)-startupplugins/org.eclipse.equin ...

  7. android 获取所有SD卡目录

    //返回sd卡路径public static List<String> getStorageDirectories(Context context) { StorageManager sm ...

  8. javascript当中的构造函数的用法

    5)构造函数的用法: 例 3.5.1 <head>    <meta http-equiv="content-type" content="text/h ...

  9. jdk8-》joining、groupingBy、summarizingInt函数

    拼接函数 Collectors.joining // 3种重载方法 Collectors.joining() Collectors.joining("拼接符") Collector ...

  10. vue的一些基础知识点,后续会更新最全的vue知识点

    axios中jq的基础 jq语法 $(this).hide() 隐藏当前的html元素 $(''#test").hide() 隐藏id='test'的元素 添加新的 HTML 内容 我们将学 ...