zoukankan      html  css  js  c++  java
  • 【hdu 1533】Going Home

    【链接】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;
    }
    


  • 相关阅读:
    如何防止多个人同时编辑文件
    通过Word实现表单套打
    偏前端
    偏前端
    偏前端
    偏前端 -webpack打包之(安装webpack)
    偏前端
    偏前端
    偏前端
    偏前端--之小白学习本地存储与cookie
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626088.html
Copyright © 2011-2022 走看看