文章标题 HDU 1533 : Going Home (最小费用最大流)

来源:互联网 发布:漫画下载软件 编辑:程序博客网 时间:2024/06/06 05:40

Going Home

题目链接
题意:在n*m的矩形上,有房子和人, 人到达房子的话费是曼哈顿距离,然后每个人走到一个房子,求最小的费用。
分析:最小费用最大流的模板
代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <set>#include <map>#include <algorithm>#include <math.h>#include <vector>using namespace std;typedef long long ll;const int inf=1000000;const int mod=1e9+7;const int maxn=100*100+10;const int M=100000*2+10;struct Edge{    int to,nex,cap,flow,cost;};struct MFMC{    Edge edge[M];    int head[maxn],tot;    int pre[maxn],dis[maxn];    bool vis[maxn];    int N;//节点的总个数,节点编号从0~N-1;    void init(int n){        N=n;        tot=0;        memset (head,-1,sizeof (head));    }    void addedge(int u,int v,int cap,int cost){        edge[tot]=Edge{v,head[u],cap,0,cost};        head[u]=tot++;        edge[tot]=Edge{u,head[v],0,0,-cost};        head[v]=tot++;    }    bool spfa(int s,int t){        queue<int>q;        for (int i=0;i<N;i++){            dis[i]=inf;            vis[i]=false;            pre[i]=-1;        }        dis[s]=0;        vis[s]=true;        q.push(s);        while (!q.empty()){            int u=q.front();q.pop();            vis[u]=false;            for (int i=head[u];i!=-1;i=edge[i].nex){                int v=edge[i].to;                if (edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){                    dis[v]=dis[u]+edge[i].cost;                    pre[v]=i;                    if (!vis[v]){                        vis[v]=true;                        q.push(v);                    }                }            }        }        if (pre[t]==-1)return false;        else return true;    }    int minCostMaxflow(int s,int t,int &cost){        int flow=0;        cost=0;        while (spfa(s,t)){            int Min=inf;            for (int i=pre[t];i!=-1;i=pre[edge[i^1].to]){                if ((Min>edge[i].cap-edge[i].flow)){                    Min=edge[i].cap-edge[i].flow;                }            }            for (int i=pre[t];i!=-1;i=pre[edge[i^1].to]){                edge[i].flow+=Min;                edge[i^1].flow-=Min;                cost+=edge[i].cost*Min;            }            flow+=Min;        }        return flow;    }}mfmc;struct node {    int x,y;};vector<node>house,man;int n,m;char mp[maxn][maxn];int main(){    while (scanf ("%d%d",&n,&m)!=EOF){        if (n==0&&m==0)break;        mfmc.init(maxn);        house.clear(),man.clear();        for (int i=1;i<=n;i++){            scanf ("%s",mp[i]+1);            for (int j=1;j<=m;j++){                if (mp[i][j]=='H')house.push_back(node{i,j});                else if (mp[i][j]=='m')man.push_back(node{i,j});             }        }        int s=man.size()*2+1,t=man.size()*2+2;        for (int i=0;i<man.size();i++){            mfmc.addedge(s,i,1,0);            for (int j=0;j<house.size();j++){                int dis=fabs(man[i].x-house[j].x)+fabs(man[i].y-house[j].y);                mfmc.addedge(i,man.size()+j,1,dis);            }            mfmc.addedge(man.size()+i,t,1,0);        }        int cost=0;        mfmc.minCostMaxflow(s,t,cost);        printf ("%d\n",cost);    }    return 0;}