【链接】http://acm.hdu.edu.cn/showproblem.php?pid=1533


【题意】


一个N*M地图上有相同数量的字符H和字符m,m代表一个 人,H代表一个房子。人到房子的花销是它们在图中的曼哈顿距离,问你让所有人回到房子所需要的最小费用(一个房子只能容纳一个人)。

【题解】


费用流;
建立一个超级源点,它和每个房子都有一条边相连,边的容量为1,费用为0;
建立一个超级汇点,他和每个人都有一条边相连,边的容量为1,费用为0;
每个房子和每个人都有一条边,容量为1,费用为它们的曼哈顿距离
这个图的最大流肯定是房子的个数.

则这个时候跑一下最小费用最大流就好.

【错的次数】


0

【反思】


第一次写费用流

【代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define ri(x) scanf("%d",&x)
#define rl(x) scanf("%lld",&x)
#define rs(x) scanf("%s",x)
#define oi(x) printf("%d",x)
#define ol(x) printf("%lld",x)
#define oc putchar(' ')
#define os(x) printf(x)
#define all(x) x.begin(),x.end()
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 100;
const int NN = 3e4;
const int INF = 0x3f3f3f3f; struct abc{
    int from,en,flow,nex,cost;
}; int n,m,totm,fir[2*N+50],dis[N*2+50],pre[2*N+50],mi[2*N+50],ans;
char s[N+10][N+10];
vector <pii> H,M;
abc bian[NN];
bool inq[2*N+50];
queue <int> dl; void add(int x,int y,int flow,int cost){
    bian[totm].nex = fir[x];
    fir[x] = totm;
    bian[totm].from = x;
    bian[totm].en = y;
    bian[totm].cost = cost;
    bian[totm].flow = flow;
    totm++;     bian[totm].nex = fir[y];
    fir[y] = totm;
    bian[totm].from = y;
    bian[totm].en = x;
    bian[totm].cost = -cost;
    bian[totm].flow = 0;
    totm++;
} bool spfa(int s,int t){
    ms(dis,INF),ms(inq,0),ms(mi,INF);
    dis[s] = 0,inq[s] = 1;
    dl.push(s);
    pre[t] = -1;
    while (!dl.empty()){
        int x = dl.front();
        inq[x] = false;
        dl.pop();
        for (int i = fir[x];i!=-1;i = bian[i].nex){
            int y = bian[i].en;
            if (bian[i].flow && dis[y] > dis[x] + bian[i].cost){
                dis[y] = dis[x] + bian[i].cost;
                mi[y] = min(bian[i].flow,mi[x]);
                pre[y] = i;
                if (!inq[y]){
                    inq[y] = true;
                    dl.push(y);
                }
            }
        }
    }
    if (pre[t]==-1) return false;
    int now = t;
    while (now != s){
        int temp = pre[now];
        bian[temp].flow -= mi[t];
        bian[temp^1].flow += mi[t];
        now = bian[temp].from;
        ans += mi[t]*bian[temp].cost;
    }
    return true;
} int main(){
    //Open();
    //Close();
    while (~ri(n)){
        ans = 0;
        ri(m);
        if (n == 0 && m == 0) break;
        rep1(i,0,n-1)
            rs(s[i]);
        H.clear(),M.clear();
        rep1(i,0,n-1)
            rep1(j,0,m-1)
                if (s[i][j]=='H')
                    H.pb(mp(i,j));
                else if (s[i][j]=='m')
                        M.pb(mp(i,j));
        totm = 0;
        ms(fir,255);
        int len1 = H.size(),len2 = M.size();
        rep1(i,0,len1-1) add(0,i+1,1,0);
        rep1(i,0,len2-1) add(i+1+len1,len1+len2+1,1,0);
        rep1(i,0,len1-1)
            rep1(j,0,len2-1)
                add(i+1,len1+j+1,1,abs(M[j].fi-H[i].fi)+abs(M[j].se-H[i].se));
        while (spfa(0,len1+len2+1));
        oi(ans);puts("");
    }
    return 0;
}

【hdu 1533】Going Home的更多相关文章

  1. 【HDU 1533】 Going Home (KM)

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

  2. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  3. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  4. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  5. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  6. 【HDU 2196】 Computer (树形DP)

    [HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...

  7. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  8. 【hdu 1043】Eight

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...

  9. 【HDU 3068】 最长回文

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...

随机推荐

  1. EBS TimeZone问题

    记录问题 :  http://blog.csdn.net/cymm_liu/article/details/29234919     --     Oracle 数据库中的 时间 时区 http:// ...

  2. IOS &#39;NSInternalInconsistencyException&#39;

    今天想写一个请求的天气.好的.废话不多说.先贴代码: 使用AFNetWorking 发送get请求,可是一直报错  IOS 'NSInternalInconsistencyException', re ...

  3. Linux系统的LOG日志文件及入侵后日志的清除

    UNIX网管员主要是靠系统的LOG,来获得入侵的痕迹.当然也有第三方工具记录入侵系统的 痕迹,UNIX系统存放LOG文件,普通位置如下: /usr/adm - 早期版本的UNIX/var/adm -  ...

  4. Linux下清除系统日志方法

    摘要:相信大家都是用过Windows的人.对于Windows下饱受诟病的各种垃圾文件都需要自己想办法删除,不然你的系统将会变得越来越大,越来越迟钝!windows怎么清理垃圾相信大家都知道的,那么li ...

  5. 初学PHP&MySQL 2014-05-31 12:40 92人阅读 评论(0) 收藏

    PHP echo  print 都能输出文本 date(format,timestamp)可以格式化时间戳 mktime()可以返回指定日期的时间戳 include 'filename'或者 requ ...

  6. Docker安装配置教程

    Docker公开课 1 Docker介绍 1.1 Docker是什么 云计算\云服务 IAAS(基础设施即服务).PAAS(平台即服务).SAAS(软件即服务) Docker到底是什么呢? Docke ...

  7. Docker -- 系统整洁之道 -- 0

    在我的小 rmbp 256G的硬盘里,实在是装不下100多个G的虚拟机了,所以想把一些东西迁移到这两年很火的Docker下,Docker以前也有过一两次,只是按着别人给的用法用的,具体的一些细节并没有 ...

  8. AIX 软件包结构

    AIX installp软件包结构  1. usr部分 2. / (root)部分 3. share部分    AIX 为了实现在客户机 / 服务器环境下安装的灵活性将安装包划分为 usr 部分 .r ...

  9. Perl线程介绍

    Perl 中的线程 本文首先概述了线程的概念和意义,接着回顾了 Perl 语言中对线程支持的演化历史,然后通过一系列示例重点介绍了 Perl 中线程的实现,数据的共享以及线程间的同步,最后归纳并总结了 ...

  10. 紫书 例题 9-7 UVa 11584 (线性结构上的动态规划)

    这道题判断回文串的方法非常的秀! 这里用到了记忆化搜索,因为会有很多重复 同时用kase来区分每一组数据 然后还有用递归来判断回文,很简洁 然后这种线性结构的动态规划的题,就是把 当前的这个数组分成两 ...