首页 > 代码库 > 最小费用最大流2

最小费用最大流2

#include <stdio.h>#include <iostream>#include <string.h>#include<cmath>using namespace std;const int N=300;const int MAXE=200000;const int inf=1<<30;int head[N],ep;int d[N],pre[N];bool vis[N];int q[MAXE];struct Edge{    int u,v,c,w,next;}edge[MAXE];void addedge(int u,int v,int w,int c)//u v 费用 容量{    edge[ep].u=u;    edge[ep].v=v;    edge[ep].w=w;    edge[ep].c=c;    edge[ep].next=head[u];    head[u]=ep++;    edge[ep].v=u;    edge[ep].u=v;    edge[ep].w=-w;    edge[ep].c=0;    edge[ep].next=head[v];    head[v]=ep++;}int SPFA(int src,int des){    int l,r;    memset(pre,-1,sizeof(pre));    memset(vis,0,sizeof(vis));    for(int i=0;i<=des;i++) d[i]=inf;    d[src]=0;    l=0;r=0;    q[r++]=src;    vis[src]=1;    while(l<r)    {        int u=q[l++];        vis[u]=0;        for(int j=head[u];j!=-1;j=edge[j].next)        {            int v=edge[j].v;            if(edge[j].c>0&&d[u]+edge[j].w<d[v])            {                d[v]=d[u]+edge[j].w;                pre[v]=j;                if(!vis[v])                {                    vis[v]=1;                    q[r++]=v;                }            }        }    }    if(d[des]==inf)        return 0;    return 1;}int MCMF(int src,int des){    int flow=0,ans=0;//flow是得到的最大流的值 ans得到的是最小的费用    while(SPFA(src,des))    {        ans+=d[des];        int u=des;        int mini=inf;        while(u!=src)        {            if(edge[pre[u]].c<mini)                mini=edge[pre[u]].c;                u=edge[pre[u]].u;        }        flow+=mini;        u=des;        while(u!=src)        {            edge[pre[u]].c-=mini;            edge[pre[u]^1].c+=mini;            u=edge[pre[u]].u;        }    }    return ans;}struct man{    int x;    int y;}M[111];struct house{    int x,y;}H[111];char str[111];int main(){    int n,m,mcnt,hcnt,i,j,src,des;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(!n&&!m) break;        ep=0;        memset(head,-1,sizeof(head));        mcnt=hcnt=0;        for(i=0;i<n;i++)        {            scanf("%s",str);            for(j=0;j<m;j++)            {                if(str[j]==H)                {                    hcnt++;                    H[hcnt].x=i; H[hcnt].y=j;                }                else if(str[j]==m)                {                    mcnt++;                    M[mcnt].x=i; M[mcnt].y=j;                }            }        }        for(i=1;i<=mcnt;i++)        {            for(j=1;j<=hcnt;j++)            {                int dis=abs(M[i].x-H[j].x)+abs(M[i].y-H[j].y);                addedge(i,mcnt+j,dis,1);                //addedge(mcnt+j,i,dis,1);            }        }        src=0;        des=mcnt+hcnt+1;        for(i=1;i<=mcnt;i++)          addedge(src,i,0,1);        for(j=1;j<=hcnt;j++)            addedge(mcnt+j,des,0,1);        int ans=MCMF(src,des);        printf("%d\n",ans);    }    return 0;}