费用流模板(带权二分图匹配)——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的主要内容,如果未能解决你的问题,请参考以下文章

带权二分图最大匹配 P1500

hdu 2255奔小康赚大钱 KM算法模板

[POJ2195]Going Home(带权最大匹配,KM,最小费用流)

二分图/网络流/最小割/最大流/最小费用最大流等等 模板

POJ 2195 & HDU 1533 Going Home(最小费用最大流)

二分图匹配入门专题1K - Going Home hdu1533km匹配