POJ 2195 min_cost_max_flow

来源:互联网 发布:标签设计软件哪种好 编辑:程序博客网 时间:2024/05/16 02:51

给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致。man每移动一格需花费$1(即单位费用=单位距离),一间house只能入住一个man。现在要求所有的man都入住house,求最小费用。

建图:
s连每个房间 c为1 cost为0
每个人连t c为1 cost为0
每个房间连每个人 c为1 cost为abs(x)+abs(y)

然后跑最小费用流

算法一次敲对了,数组开小了,坑爹啊


#include<cstdio>#include<queue>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int n_max=205;const int m_max=21505; const int inf=1<<30;struct edge{int u,v,cap,cost,pre;void add(int pu,int pv,int pcap,int pcost,int ppre){u=pu;v=pv;cap=pcap;cost=pcost;pre=ppre;}}e[m_max];int ne;int head[n_max];int min_cost,max_flow;struct point{int x,y;void add(int xx,int yy){x=xx;y=yy;}}hou[n_max],man[n_max];int nhou,nman;void init(){ne=0;memset(head,-1,sizeof(head));}void addedge(int u,int v,int cap,int cost){e[ne].add(u,v,cap,cost,head[u]);head[u]=ne++;e[ne].add(v,u,0,-cost,head[v]);head[v]=ne++;}void min_cost_max_flow(int s,int t){min_cost=max_flow=0;while(true){int p[n_max];memset(p,-1,sizeof(p));int d[n_max];int i;for(i=0;i<n_max;i++){d[i]=inf;}d[s]=0;bool inq[n_max];memset(inq,0,sizeof(inq));queue<int> q;q.push(s);inq[s]=true;int u,v;while(!q.empty()){u=q.front();q.pop();inq[u]=false;for(i=head[u];i!=-1;i=e[i].pre){v=e[i].v;if(e[i].cap&&d[v]>d[u]+e[i].cost){d[v]=d[u]+e[i].cost;p[v]=i;if(!inq[v]){q.push(v);inq[v]=true;}}}}if(d[t]==inf){break;}int nmin=inf;for(i=p[t];i!=-1;i=p[e[i].u]){nmin=min(nmin,e[i].cap);}for(i=p[t];i!=-1;i=p[e[i].u]){e[i].cap -= nmin;e[i^1].cap += nmin;}min_cost += d[t]*nmin;max_flow += nmin;}}int main(){char str[110];int n,m,s,t;while(~scanf("%d%d",&n,&m)){nhou=nman=0;if(n+m==0){break;}int i,j;for(i=0;i<n;i++){scanf("%s",str);for(j=0;j<m;j++){if(str[j]=='H'){hou[++nhou].add(i,j);}else if(str[j]=='m'){man[++nman].add(i,j);}}}s=0;t=nhou+nman+1;init();for(i=1;i<=nhou;i++){for(j=1;j<=nman;j++){int cost=fabs(hou[i].x-man[j].x) + fabs(hou[i].y-man[j].y);addedge(i,nhou+j,1,cost);}}for(i=1;i<=nhou;i++){addedge(s,i,1,0);}for(j=1;j<=nman;j++){addedge(nhou+j,t,1,0);}min_cost_max_flow(s,t);printf("%d\n",min_cost);}return 0;}