poj 2195 最小费用最大流

来源:互联网 发布:java swap docker 编辑:程序博客网 时间:2024/06/05 11:27
#include<iostream>#include<cstdio>#include<cmath>#include<string>#include<queue>using namespace std;#define inf 10000000#define N 120#define min(a,b) (a)>(b)?(b):(a)char si[1000];int map[N*2][N*2];int cost[N*2][N*2];int fab(int a){if(a>0)return a;elsereturn -a;}typedef struct point{int x,y;}rr;point man[N],horse[N];int m,n,s,t;int pre[N*2];int spfa(){int dis[N*2];bool vis[N*2];int i;for(i=0; i<=t; i++){dis[i]=inf;vis[i]=false;}dis[0]=0;vis[0]=true;queue<int>q;q.push(s);while(!q.empty()){int k=q.front();q.pop();vis[k]=false;for(i=0; i<=t; i++){if(map[k][i]!=0 && dis[i]>dis[k]+cost[k][i]){dis[i]=dis[k]+cost[k][i];pre[i]=k;if(vis[i]==false){q.push(i);vis[i]=true;}}}}if(dis[t]!=inf)return 1;elsereturn 0;}int fond(){int i,j;int f=inf;j=0;while(spfa()){for(i=t; i!=s; i=pre[i])f=min(f,map[pre[i]][i]);for(i=t; i!=s; i=pre[i]){map[pre[i]][i]-=f;map[i][pre[i]]+=f;j+=cost[pre[i]][i]*f;}}return j;}int main(){int i,j,k,p;while(scanf("%d%d",&n,&m)){if(n==0 && m==0)break;s=0;k=1;p=1;for(i=1; i<=n; i++){scanf("%s",si);for(j=0; j<m; j++){if(si[j]=='H'){horse[k].x=i;horse[k++].y=j+1;}if(si[j]=='m'){man[p].x=i;man[p++].y=j+1;}}}t=p+k-1;for(i=0; i<=t; i++)for(j=0; j<=t; j++)map[i][j]=cost[i][j]=0; //建图1到k-1为horse,k到p-k-2为man        for(i=1; i<k; i++)          map[s][i]=1;//最多跑那么多的步子for(i=1; i<k; i++)for(j=1; j<p; j++){map[i][j+k-1]=1;cost[i][j+k-1]=fab(horse[i].x-man[j].x)+fab(horse[i].y-man[j].y);cost[j+k-1][i]=-cost[i][j+k-1];}for(j=1; j<p; j++)map[j+k-1][t]=1;int sum=0;sum+=fond();printf("%d\n",sum);}return 0;}