poj 2195 Going Home

来源:互联网 发布:剑侠情缘手游网络异常 编辑:程序博客网 时间:2024/05/18 19:39

最小费用最大流,直接贴模板过,注意数组开小了会RE

/*最小费用最大流*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;


struct node
{
    int u,v,cost,flow,next;
};




struct Pos
{
    int row;
    int col;
}man[205],house[205];


int n,m;


const int INF=1000000;
node edges[2000005];
int head[505],e;
int pre[505],in[505],cost[505],flow[505];
int s,t;
queue<int> Q;


void add(int u,int v,int flow,int cost)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].cost=cost;
    edges[e].flow=flow;
    edges[e].next=head[u];
    head[u]=e++;
}


void Add(int u,int v,int flow,int cost)
{
    add(u,v,flow,cost);
    add(v,u,0,-cost);
}


int SPFA(int s,int t)
{
    int i,u,v;


    memset(pre,-1,sizeof(pre));
    memset(flow,0,sizeof(flow));
    memset(in,0,sizeof(in));
    for(i=0;i<=t;i++) cost[i]=INF;
    while(!Q.empty()) Q.pop();
    Q.push(s);
    in[s]=1;
    flow[s]=INF;
    cost[s]=0;
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();


        in[u]=0;
        for(i=head[u];i!=-1;i=edges[i].next)
        {
            v=edges[i].v;
            if(edges[i].flow>0&&cost[v]>cost[u]+edges[i].cost)
            {
                cost[v]=cost[u]+edges[i].cost;
                pre[v]=i;
                flow[v]=min(flow[u],edges[i].flow);
                if(!in[v])
                {
                    in[v]=1;
                    Q.push(v);
                }
            }
        }
    }
    return flow[t];
}


int MCMF(int s,int t)
{
    int mincost=0,minflow,i;
    while(minflow=SPFA(s,t))
    {
        for(i=pre[t];i!=-1;i=pre[edges[i].u])
        {
            mincost+=minflow*edges[i].cost;
            edges[i].flow-=minflow;
            edges[i^1].flow+=minflow;
        }
    }
    return mincost;
}


int main()
{
    int mc,nc;
    while(scanf("%d %d",&n,&m)&&n!=0&&m!=0)
    {
        memset(head,-1,sizeof(head));
        char s[105];
        mc = nc = 1;
        for(int i = 0;i<n;i++)
            {
                scanf("%s",s);
                for(int j = 0;j<m;j++)
                {
                    if(s[j]=='m')
                       {
                           man[mc].row = i;
                           man[mc++].col = j;
                       }
                    if(s[j]=='H')
                    {
                        house[nc].row = i;
                        house[nc++].col = j;
                    }
                }
            }
        for(int i = 1;i<mc;i++)
            for(int j = 1;j<nc;j++)
            {
                int len = abs((double)(house[j].row-man[i].row))+abs((double)(house[j].col-man[i].col));
                Add(i,mc+j-1,1,len);
            }
        for(int i = 1;i<mc;i++)
            Add(0,i,1,0);
        for(int j = 1;j<nc;j++)
            Add(mc-1+j,mc+nc-1,1,0);
        int ans = MCMF(0,mc+nc-1);
        printf("%d\n",ans);
    }
    return 0;
}

原创粉丝点击