标签:unit 容量 row nts you rev getchar open term
Input
Output
Sample Input
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
Sample Output
2 10 28
思路
应该算是这个算法的板子题了,感觉还是只有看自己的代码才是最容易懂的。
cap表示边的容量,w表示费用。
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #define fuck(x) cout<<#x<<" = "<<x<<endl; #define ls (t<<1) #define rs ((t<<1)+1) using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1024; const int inf = 2.1e9; const ll Inf = 999999999999999999; const int mod = 1000000007; const double eps = 1e-6; const double pi = acos(-1); int n,m; char mp[108][108]; struct node { int x,y; }p1[maxn],p2[maxn]; int Head[maxn],Next[maxn*maxn],v[maxn*maxn],w[maxn*maxn],cap[maxn*maxn],cnt; int t1,t2;int ans; void init() { t1=1;cnt=t2=ans=0; memset(Head,-1,sizeof(Head)); } void add(int x,int y,int z,int f){ // cout<<x<<" "<<y<<" "<<z<<endl; v[cnt]=y; w[cnt]=z; cap[cnt]=f; Next[cnt]=Head[x]; Head[x]=cnt++; v[cnt]=x; w[cnt]=-z; cap[cnt]=0; Next[cnt]=Head[y]; Head[y]=cnt++; } bool vis[maxn]; int dis[maxn]; int prevv[maxn],preve[maxn]; int s,t; bool spfa() { queue<int>q; memset(vis,0,sizeof(vis)); for(int i=1;i<=t;i++){ dis[i]=inf; } dis[s]=0; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=false; for(int k=Head[u];k!=-1;k=Next[k]){ if(cap[k]&&dis[v[k]]>dis[u]+w[k]){ dis[v[k]]=dis[u]+w[k]; prevv[v[k]]=u; preve[v[k]]=k; if(!vis[v[k]]){ vis[v[k]]=true; q.push(v[k]); } } } } // for(int i=1;i<=t;i++){ // cout<<dis[i]<<" "; // } // cout<<endl; // getchar();getchar(); if(dis[t]==inf){return false;} else return true; } int min_cost_flow() { // fuck("???") while(spfa()){ // cout<<"____"<<endl; for(int i=t;i!=s;i=prevv[i]){ int k=preve[i]; cap[k]-=1; cap[k^1]+=1; } // cout<<endl; ans+=dis[t]; } } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){ init(); for(int i=1;i<=n;i++){ scanf("%s",mp[i]+1); for(int j=1;j<=m;j++){ if(mp[i][j]==‘m‘){p1[++t1]=node{i,j};} else if(mp[i][j]==‘H‘){p2[++t2]=node{i,j};} } } s=1;t=t1+t2+1; for(int i=2;i<=t1;i++){ add(s,i,0,1); for(int j=1;j<=t2;j++){ add(i,j+t1,abs(p1[i].x-p2[j].x)+abs(p1[i].y-p2[j].y),inf); } } for(int i=1;i<=t2;i++){ add(i+t1,t,0,1); } min_cost_flow(); printf("%d\n",ans); } return 0; }
Going Home POJ - 2195 (最小费用最大流)
标签:unit 容量 row nts you rev getchar open term
原文地址:https://www.cnblogs.com/ZGQblogs/p/10177069.html