1. 程式人生 > >POJ - 2195 最小費用最大流

POJ - 2195 最小費用最大流

!= cond print false char air double 題意 memset

題意:每個人到每個房子一一對應,費用為曼哈頓距離,求最小的費用

題解:單源點匯點最小費用最大流,每個人和房子對於建邊

技術分享
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include
<cstring> #include<iostream> #include<algorithm> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define
rs m+1,r,rt<<1|1 using namespace std; using namespace __gnu_cxx; const double g=10.0,eps=1e-7; const int N=300+10,maxn=10000+10,inf=0x3f3f3f; struct edge{ int to,Next,c; int cost; }e[maxn<<2]; int cnt,head[N]; int s,t,ans[N][N]; int dis[N],path[N],pre[N]; void add(int u,int
v,int c,int cost) { // cout<<u<<" "<<v<<" "<<c<<" "<<cost<<endl; e[cnt].to=v; e[cnt].c=c; e[cnt].cost=cost; e[cnt].Next=head[u]; head[u]=cnt++; e[cnt].to=u; e[cnt].c=0; e[cnt].cost=-cost; e[cnt].Next=head[v]; head[v]=cnt++; } bool spfa() { memset(pre,-1,sizeof pre); memset(dis,inf,sizeof dis); dis[s]=0; queue<int>q; q.push(s); while(!q.empty()) { int x=q.front(); q.pop(); for(int i=head[x];~i;i=e[i].Next) { int te=e[i].to; if(e[i].c>0&&dis[x]+e[i].cost<dis[te]) { dis[te]=dis[x]+e[i].cost; pre[te]=x; path[te]=i; q.push(te); } } } return pre[t]!=-1; } int mincostmaxflow() { int cost=0,flow=0; while(spfa()) { int f=inf; for(int i=t;i!=s;i=pre[i]) if(f>e[path[i]].c) f=e[path[i]].c; flow+=f; cost+=dis[t]*f; for(int i=t;i!=s;i=pre[i]) { e[path[i]].c-=f; e[path[i]^1].c+=f; } } return cost; } void init() { cnt=0; memset(head,-1,sizeof head); } int main() { /* ios::sync_with_stdio(false); cin.tie(0);*/ int n,m; while(~scanf("%d%d",&n,&m)) { if(!n&&!m)break; init(); int house=0,man=0; pii ho[N],ma[N]; for(int i=1;i<=n;++i) { char a[N]; scanf("%s",a+1); for(int j=1;j<=m;j++) { if(a[j]==H)ho[++house]=mp(i,j); else if(a[j]==m)ma[++man]=mp(i,j); } } for(int i=1;i<=house;i++) { for(int j=1;j<=man;j++) { int cost=abs(ho[i].fi-ma[j].fi)+abs(ho[i].se-ma[j].se); // cout<<i<<" "<<j<<" "<<cost<<endl; add(i,house+j,inf,cost); // add(house+j,i,inf,cost); } } s=house+man+1,t=house+man+2; for(int i=1;i<=house;i++)add(s,i,1,0); for(int i=1;i<=man;i++)add(i+house,t,1,0); printf("%d\n",mincostmaxflow()); } return 0; } /******************* ********************/
View Code

POJ - 2195 最小費用最大流