• Going Home(MCMF)


    http://poj.org/problem?id=2195

    题意:在一个n*m的图中,'m'代表人,'H'代表房子,人每移动一次的费用为1,求所有人移动到房子里的最小花费。

    思路:最小费用最大流问题。关键是建图,建好图后就是MCMF的模板题了。。

            关于建图:增加一个原点S,一个汇点T, S与所有人相连,容量为1,花费为0;每个人与所有房子相连,容量为1,花费为|人与房子的水平距离|+|人与房子的垂直距离|;最后所有的房子 与汇点相连,容量为1,花费为0。

           关于算法:多次spfa找增广路,然后求最大流。最小花费+=原点到汇点的最小距离*每次增光后的最大流量

      1 #include <stdio.h>
      2 #include <iostream>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 #include <string.h>
      6 #include <queue>
      7 using namespace std;
      8 
      9 const int N=505;
     10 const int INF=1<<28;
     11 struct node
     12 {
     13     int x,y;
     14 } m[N],h[N];
     15 int cap[N][N],cost[N][N];
     16 int pre[N],vis[N],dis[N];
     17 int cntm,cnth,t;
     18 
     19 int spfa()
     20 {
     21     queue<int>q;
     22     for (int i = 0; i <= t; i++)
     23     {
     24         dis[i] = INF;
     25         vis[i] = 0;
     26         pre[i] = -1;
     27     }
     28     dis[0]=0;
     29     q.push(0);
     30     vis[0] = 1;
     31     while(!q.empty())
     32     {
     33         int u = q.front();
     34         vis[u] = 0;
     35         q.pop();
     36         for (int i = 0; i <= t; i++)
     37         {
     38             if (cap[u][i]&&dis[i]>dis[u]+cost[u][i])
     39             {
     40                 pre[i] = u;
     41                 dis[i] = dis[u]+cost[u][i];
     42                 if (!vis[i])
     43                 {
     44                     q.push(i);
     45                     vis[i] = 1;
     46                 }
     47             }
     48         }
     49     }
     50     if (dis[t]==INF)
     51         return 0;
     52     return 1;
     53 }
     54 int MCMF()
     55 {
     56     int Maxflow = INF;
     57     int Mincost = 0;
     58     while(spfa())
     59     {
     60         int u = t;
     61         while(pre[u]!=-1)
     62         {
     63             Maxflow = min(Maxflow,cap[pre[u]][u]);
     64             u = pre[u];
     65         }
     66         Mincost += dis[t]*Maxflow;
     67         u = t;
     68         while(pre[u]!=-1)
     69         {
     70             cap[pre[u]][u]-=Maxflow;
     71             cap[u][pre[u]]+=Maxflow;
     72             u = pre[u];
     73         }
     74     }
     75     return Mincost;
     76 }
     77 void build()
     78 {
     79     for (int i = 1; i <= cntm; i++)
     80     {
     81         for (int j = 1; j <= cnth; j++)
     82         {
     83             cap[i][j+cntm] = 1;
     84             cost[i][j+cntm] = abs(m[i].x-h[j].x)+abs(m[i].y-h[j].y);
     85             cost[j+cntm][i] = -cost[i][j+cntm];
     86         }
     87     }
     88     for (int i = 1; i <= cntm; i ++)
     89     {
     90         cap[0][i] = 1;
     91         cost[0][i] = 0;
     92         cap[i+cntm][t] = 1;
     93         cost[i+cntm][t] = 0;
     94     }
     95 }
     96 int main()
     97 {
     98     int row,col;
     99     while(~scanf("%d%d",&row,&col))
    100     {
    101         if (row==0&&col==0)
    102             break;
    103         char ch;
    104         cntm = 0,cnth = 0;
    105         memset(cap,0,sizeof(cap));
    106         memset(cost,0,sizeof(cost));
    107         for (int i = 1; i <= row; i++)
    108         {
    109             for (int j = 1; j <= col; j++)
    110             {
    111                 cin>>ch;
    112                 if (ch=='m')
    113                 {
    114                     m[++cntm].x = i;
    115                     m[cntm].y = j;
    116                 }
    117                 if (ch=='H')
    118                 {
    119                     h[++cnth].x = i;
    120                     h[cnth].y = j;
    121                 }
    122             }
    123         }
    124         t = cnth+cntm+1;
    125         build();
    126         int Mincost = MCMF();
    127         printf("%d
    ",Mincost);
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    Nacos-服务注册
    left join多表使用聚合函数count数据出错
    macos报 svn: error: The subversion command line tools are no longer provided by Xcode
    解决mac OSX下安装git出现的"git命令需要使用开发者工具。您要现在安装该工具吗"(19款Mac)
    JSP 页面 jstl 时间戳 long型转时间
    jdk生成证书,网站请求变成https
    java从数据库读取菜单,递归生成菜单树
    mysql PacketTooBigException 的处理方式
    用注解方式写定时任务
    eclipse快捷键
  • 原文地址:https://www.cnblogs.com/lahblogs/p/3546648.html
Copyright © 2020-2023  润新知