费用流模板(带权二分图匹配)——hdu1533
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了费用流模板(带权二分图匹配)——hdu1533相关的知识,希望对你有一定的参考价值。
/* 带权二分图匹配 用费用流求,增加源点s 和 汇点t */ #include<bits/stdc++.h> using namespace std; #define maxn 10005 #define maxm 200005 struct Edgeint to,nxt,w,c;e[maxm<<1]; int head[maxn],tot,n,m,s,t,ans,maxflow; char mp[maxn][maxn]; vector<pair<int,int> >M,H; void add(int u,int v,int w,int c) e[tot].to=v;e[tot].w=w;e[tot].c=c;e[tot].nxt=head[u];head[u]=tot++; e[tot].to=u;e[tot].w=0;e[tot].c=-c;e[tot].nxt=head[v];head[v]=tot++; int d[maxn],v[maxn],incf[maxn],pre[maxn]; bool spfa() queue<int>q; memset(d,0x3f,sizeof d); memset(v,0,sizeof v); q.push(s);d[s]=0;v[s]=1; incf[s]=1<<30; while(q.size()) int x=q.front();q.pop();v[x]=0; for(int i=head[x];i!=-1;i=e[i].nxt) int y=e[i].to; if(e[i].w==0)continue; if(d[y]>d[x]+e[i].c) d[y]=d[x]+e[i].c; incf[y]=min(incf[x],e[i].w); pre[y]=i; if(!v[y])v[y]=1,q.push(y); if(d[t]==0x3f3f3f3f)return false; return true; void update() int x=t; while(x!=s) int i=pre[x]; e[i].w-=incf[t]; e[i^1].w+=incf[t]; x=e[i^1].to; maxflow+=incf[t]; ans+=d[t]*incf[t]; void init() memset(head,-1,sizeof head); tot=ans=maxflow=0; M.clear();H.clear(); int dis(pair<int,int> a,pair<int,int> b) return abs(a.first-b.first)+abs(a.second-b.second); int main() while(cin>>n>>m&&n) init(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("\n%c",&mp[i][j]); if(mp[i][j]==‘m‘) M.push_back(make_pair(i,j)); if(mp[i][j]==‘H‘) H.push_back(make_pair(i,j)); s=0,t=2*M.size()+1; for(int i=0;i<M.size();i++) add(s,i+1,1,0); for(int i=0;i<H.size();i++) add(i+1+M.size(),t,1,0); for(int i=0;i<M.size();i++) for(int j=0;j<H.size();j++) add(i+1,j+1+M.size(),1,dis(M[i],H[j])); while(spfa()) update(); cout<<ans<<‘\n‘;
以上是关于费用流模板(带权二分图匹配)——hdu1533的主要内容,如果未能解决你的问题,请参考以下文章
[POJ2195]Going Home(带权最大匹配,KM,最小费用流)