zoukankan      html  css  js  c++  java
  • HDU4289Control(最大流)

    SAP最大流。。额额额额额额额额,看不懂的说,把题解贴出来吧,好歹也能算个模版。。

    HDU-4289-Control

    本题可以看成是求A到B的最大流,因为权值在点上,还要进行拆点。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define MAXM 100000
    #define MAXN 405
    #define INF 2e9
    struct eee{
        int v,cap,next;
        eee(){};
        eee(int v,int w):v(v),cap(w){}
    }edge[MAXM];
    
    int first[MAXN];
    int d[MAXN];//距离标号
    int pre[MAXN];
    int numh[MAXN];//GAP数组
    int curfirst[MAXN];//各点当前弧
    int flow[MAXN];
    int e;
    int n;
    int m;
    int S,D;
    void init(){
        memset(first,-1,sizeof(first));
        e=0;
    }
    void add(int u,int v,int w){
        edge[e]=eee(v,w);
        edge[e].next=first[u];
        first[u]=e++;
        edge[e]=eee(u,0);
        edge[e].next=first[v];
        first[v]=e++;
    }
    int sap_maxflow(int st,int en){
    
        int ans=0;
        for(int i=1;i<=n;i++)
        curfirst[i]=first[i];
        memset(d,0,sizeof(d));
        memset(numh,0,sizeof(numh));
        numh[0]=n;
        int i=st;
        bool ok;
        int MIN;
        int aug=INF;
    
        while(d[st]<n){
            flow[st]=aug;
            ok=false;
            for(int j=curfirst[i];j!=-1;j=edge[j].next){
                if(edge[j].cap&&d[i]==d[edge[j].v]+1){
                    ok=true;
                    aug=min(aug,edge[j].cap);
                    curfirst[i]=j;
                    i=edge[j].v;
                    pre[i]=j;
                    if(i==en){
                        ans+=aug;
                        for(;i!=st;i=edge[pre[i]^1].v){
                            edge[pre[i]].cap-=aug;
                            edge[pre[i]^1].cap+=aug;
                        }
                        aug=INF;
                    }
                }
            }
            if(ok)continue;
            MIN=n-1;
            for(int j=first[i];j!=-1;j=edge[j].next)
                if(edge[j].cap&&d[edge[j].v]<MIN){
                    MIN=d[edge[j].v];
                    curfirst[i]=j;
                }
                if(--numh[d[i]]==0)break;
                d[i]=MIN+1;
                numh[d[i]]++;
                if(i!=st){
                    i=edge[pre[i]^1].v;
                    aug=flow[i];
                }
            }
        return ans;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)==2){
            scanf("%d%d",&S,&D);
            init();
            int a,b;
            add(0,S,INF);//增加超级源点
            add(D+n,2*n+1,INF);//增加超级汇点
            for(int i=1;i<=n;i++){
                scanf("%d",&a);
                add(i,i+n,a);
                add(i+n,i,a);
            }
            for(int i=0;i<m;i++){
                scanf("%d%d",&a,&b);
                add(a+n,b,INF);
                add(b+n,a,INF);
            }
            S=0;D=2*n+1;
            n=n*2+2;
            printf("%d\n",sap_maxflow(S,D));
        }
        return 0;
    }
    

      

  • 相关阅读:
    学习完vue指令 做的一个学生信息录入系统
    vue常用指令总结
    vue介绍以及相关概念理解大全
    class类
    javascript闭包详解
    前端必看网站(一直更新中)
    微信小程序wx.getUserInfo获取用户信息
    微信小程序自定义组件注意事项
    微信小程序自定义选项卡
    uni-app开发注意事项及常用样式
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2696214.html
Copyright © 2011-2022 走看看