• 费用流模板(带权二分图匹配)——hdu1533


    /*
    带权二分图匹配
    用费用流求,增加源点s 和 汇点t 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 10005
    #define maxm 200005
    struct Edge{int 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("
    %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<<'
    ';
        }
    }
  • 相关阅读:
    BZOJ 1951: [Sdoi2010]古代猪文( 数论 )
    BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )
    BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )
    BZOJ 1935: [Shoi2007]Tree 园丁的烦恼( 差分 + 离散化 + 树状数组 )
    BZOJ 1297: [SCOI2009]迷路( dp + 矩阵快速幂 )
    BZOJ 1406: [AHOI2007]密码箱( 数论 )
    BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )
    spfa2
    spfa
    bellmanford队列优化
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10995890.html
Copyright © 2020-2023  润新知