zoj 2404 最小费用流

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2404

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>

#define maxn 550
#define maxe 100000 
#define INF  0x3f3f3f
using namespace std;

struct Edge{
    int from,to,cap,flow,cost;
    int next;
    void assign(int a,int b,int c,int d,int e,int f){
        from = a;  to = b;  cap = c; flow = d;
        cost = e;  next = f;
    }
};

struct MCMF{
    int n,cnt;
    int head[maxn];
    int d[maxn];
    Edge edges[maxe];
    int inq[maxn];
    int p[maxn];
    int res[maxn];
    
    void init(int n){
        this->n = n;
        cnt = 0;
        memset(head,-1,sizeof(head));
    }
    
    void addedge(int a,int b,int c,int d,int e){
        edges[cnt].assign(a,b,c,d,e,head[a]);
        head[a] = cnt++;
        edges[cnt].assign(b,a,0,0,-e,head[b]);
        head[b] = cnt++;
    }
    bool SPFA(int s,int t,int &flow,int& cost){
        memset(d,0x3f,sizeof(d));
        memset(inq,0,sizeof(inq));
        d[s] = 0;  inq[s] = 1; p[s] = s; res[s] = INF; res[t] = 0;
        
        queue<int> Q;
        Q.push(s);
        while(!Q.empty()){
            int u = Q.front(); Q.pop();
            inq[u] = 0;  
            
            for(int i=head[u];i!=-1;i=edges[i].next){
                Edge& e = edges[i];
                if(e.cap > e.flow && d[e.to] > d[e.from] + e.cost){
                    d[e.to] = d[e.from] + e.cost;
                    p[e.to] = i;  
                    res[e.to] = min(res[u],e.cap - e.flow);
                    if(!inq[e.to]){
                        Q.push(e.to);  inq[e.to] = 1;
                    }
                }
            }
        }
        if(res[t] == 0) return false;
        flow += res[t];   
        cost += d[t]*res[t];  
        for(int i=t;i!=s;i=edges[p[i]].from){
            edges[p[i]].flow += res[t];
            edges[p[i]^1].flow -= res[t];
        } 
        return true;
    }
}solver;
int Mincost(int s,int t){
    int flow = 0, cost = 0;
    while(solver.SPFA(s,t,flow,cost)){}
    return cost;
}

int main()
{
    //freopen("input.txt","r",stdin);
    int N,M;
    
    while(cin>>N>>M && N+M){  
        int ltail = 0;
        int rtail = 0;
        struct node{  
          int x, y;
        }l[maxn],r[maxn];
    
        char ch[105]; 
        for(int i=1;i<=N;i++){
            scanf("%s",ch);
            for(int j=0;j<M;j++){
                 if(ch[j] == 'H'){
                     r[rtail].x = i;  r[rtail++].y = j;
                }
                else if(ch[j] == 'm'){
                    l[ltail].x = i;  l[ltail++].y = j;
                }
               }
        }
           int n = ltail + rtail;
           solver.init(n);  
           int s = 0, t = n+1;
           for(int i=0;i<ltail;i++) solver.addedge(s,i+1,1,0,0);
           for(int i=0;i<rtail;i++) solver.addedge(i+1+ltail,t,1,0,0);
           for(int i=0;i<ltail;i++)
              for(int j=0;j<rtail;j++){
                    int cost = (int)abs(1.0*l[i].x-1.0*r[j].x) + (int)abs(1.0*l[i].y-1.0*r[j].y);
                    solver.addedge(i+1,ltail+1+j,1,0,cost);
              }  
           printf("%d\n",Mincost(s,t));   
    }
}
View Code

 

posted @ 2013-08-04 18:24  等待最好的两个人  阅读(249)  评论(0编辑  收藏  举报