zoukankan      html  css  js  c++  java
  • 网络流模板

    此处过滤最水的匈牙利算法。

    最大流&最小割https://www.lydsy.com/JudgeOnline/problem.php?id=2127

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define FOR(x,y) for(int i=1;i<=x;i++)for(int j=1;j<=y;j++)
    const int N=50100,M=3e5+7;
    using namespace std;
    int n,m,T,cnt,tot,ans,hd[N],lv[N],q[N],v[M],nxt[M],w[M];
    void adde(int x,int y,int z)
    {
        v[++cnt]=y,w[cnt]=z,nxt[cnt]=hd[x],hd[x]=cnt;
        v[++cnt]=x,w[cnt]=0,nxt[cnt]=hd[y],hd[y]=cnt;
    }
    bool bfs()
    {
        int qs=0,qe=1;
        memset(q,0,sizeof q);
        memset(lv,0,sizeof lv);
        q[0]=0,lv[0]=1;
        while(qs<qe)
        {
            int u=q[qs++];
            if(u==T)break;
            for(int i=hd[u];i;i=nxt[i])
            if(w[i]&&!lv[v[i]]){lv[v[i]]=lv[u]+1;q[qe++]=v[i];}
        }
        if(lv[T])return 1;return 0;
    }
    int dfs(int u,int low)
    {
        if(u==T||!low)return low;
        int sum=0;
        for(int i=hd[u];i;i=nxt[i])
        if(w[i]&&lv[v[i]]==lv[u]+1)
        {
            int tmp=dfs(v[i],min(w[i],low));
            sum+=tmp,low-=tmp,w[i]-=tmp,w[i^1]+=tmp;
            if(!low)return sum;
        }
        if(low)lv[u]=-1;
        return sum;
    }
    int id(int x,int y){return(x-1)*m+y;}
    int main()
    {
        scanf("%d%d",&n,&m);
        T=5*n*m+1,cnt=1,tot=n*m;
        int x;
        FOR(n,m)scanf("%d",&x),adde(0,id(i,j),x),ans+=x;
        FOR(n,m)scanf("%d",&x),adde(id(i,j),T,x),ans+=x;
        FOR(n-1,m)
        scanf("%d",&x),tot++,adde(0,tot,x),adde(tot,id(i,j),1e9),adde(tot,id(i+1,j),1e9),ans+=x;
        FOR(n-1,m)
        scanf("%d",&x),tot++,adde(tot,T,x),adde(id(i,j),tot,1e9),adde(id(i+1,j),tot,1e9),ans+=x;
        FOR(n,m-1)
        scanf("%d",&x),tot++,adde(0,tot,x),adde(tot,id(i,j),1e9),adde(tot,id(i,j+1),1e9),ans+=x;
        FOR(n,m-1)
        scanf("%d",&x),tot++,adde(tot,T,x),adde(id(i,j),tot,1e9),adde(id(i,j+1),tot,1e9),ans+=x;
        while(bfs())ans-=dfs(0,1e9);
        printf("%d",ans);
    }

    费用流https://www.luogu.org/problemnew/show/P3705

    #include<bits/stdc++.h>
    using namespace std;
    const int N=207;
    struct edge{int u,v,w,nxt;double c;}e[N*N*4];
    queue<int>q;
    int n,S,T,ecnt,hd[N],vis[N],pre[N];
    double a[N][N],b[N][N],d[N];
    void adde(int x,int y,int z,double c)
    {
        e[++ecnt]=(edge){x,y,z,hd[x],c},hd[x]=ecnt;
        e[++ecnt]=(edge){y,x,0,hd[y],-c},hd[y]=ecnt;
    }
    bool spfa()
    {
        for(int i=S;i<=T;i++)d[i]=-1e18,pre[i]=0;
        d[S]=0,q.push(S);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            vis[u]=0;
            for(int i=hd[u];i;i=e[i].nxt)
            if(e[i].w&&d[u]+e[i].c>d[e[i].v])
            {
                pre[e[i].v]=i,d[e[i].v]=d[u]+e[i].c;
                if(!vis[e[i].v])q.push(e[i].v),vis[e[i].v]=1;
            }
        }
        return d[T]>-1e18;
    }
    bool check()
    {
        double ret=0;
        while(spfa())
        {
            int mn=1e9+7;
            for(int i=pre[T];i;i=pre[e[i^1].v])mn=min(mn,e[i].w);
            for(int i=pre[T];i;i=pre[e[i^1].v])e[i].w-=mn,e[i^1].w+=mn;
            ret+=mn*d[T];
        }
        return ret>0;
    }
    int main()
    {
        scanf("%d",&n),T=2*n+1;
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lf",&a[i][j]);
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lf",&b[i][j]);
        double l=0,r=10086,mid;
        while(r-l>1e-7)
        {
            mid=(l+r)/2;
            ecnt=1;
            memset(hd,0,sizeof hd);
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            adde(i,j+n,1,a[i][j]-mid*b[i][j]);
            for(int i=1;i<=n;i++)adde(S,i,1,0),adde(i+n,T,1,0);
            if(check())l=mid;else r=mid;
        }
        printf("%.6lf",l);
    }

    KMhttps://www.luogu.org/problemnew/show/P4412

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1100,M=21000;
    struct edge{int u,v,nxt,w,id;}a[M],e[M];
    bool is[M];
    int n,m,cnt,hd[N],fa[N],deep[N],pre[M],f[N][N],mat[N],lx[N],rx[N],need[N],mp[N][N];
    bool vl[N],vr[N];
    void add(int x,int y,int z,int id)
    {e[++cnt]=(edge){x,y,hd[x],z,id};hd[x]=cnt;}
    void dfs(int u)
    {
        for(int i=hd[u];i;i=e[i].nxt)
        if(e[i].v!=fa[u])
        {
            fa[e[i].v]=u;
            deep[e[i].v]=deep[u]+1;
            pre[e[i].v]=i;
            dfs(e[i].v);
        }
    }
    void build(int u,int i)
    {
        int x=a[i].u,y=a[i].v;
        while(x!=y)
        {
            if(deep[x]>deep[y])swap(x,y);
            int k=pre[y];
            f[u][e[k].id]=e[k].w-a[i].w;
            y=fa[y];
        }
    }
    bool find(int x)
    {
        vl[x]=1;
        for(int i=1;i<=n;i++)
        if(!vr[i])
        {
            if(lx[x]+rx[i]==f[x][i])
            {
                vr[i]=1;
                if(!mat[i]||find(mat[i]))
                {
                    mat[i]=x;
                    return 1;
                }
            }
            else need[i]=min(need[i],lx[x]+rx[i]-f[x][i]);
        }
        return 0;
    }
    void km()
    {
        memset(mat,0,sizeof mat);
        memset(lx,0,sizeof lx);
        memset(rx,0,sizeof rx);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        lx[i]=max(lx[i],f[i][j]);
        for(int i=1;i<=n;i++)
        {
            memset(need,63,sizeof need);
            while(1)
            {
                memset(vl,0,sizeof vl);
                memset(vr,0,sizeof vr);
                if(find(i))break;
                int d=2147483647;
                for(int j=1;j<=n;j++)if(!vr[j])d=min(d,need[j]);
                for(int j=1;j<=n;j++)
                {
                    if(vl[j])lx[j]-=d;
                    if(vr[j])rx[j]+=d;
                    else need[j]-=d;
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)ans+=f[mat[i]][i];
        printf("%d",ans);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w),mp[a[i].u][a[i].v]=i;
        for(int i=1,x,y;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            is[mp[x][y]]=1;
            add(x,y,a[mp[x][y]].w,i);
            add(y,x,a[mp[x][y]].w,i);
        }
        deep[1]=1;
        dfs(1);
        for(int i=1,tp=0;i<=m;i++)
        if(!is[i])build(++tp,i);
        n=max(n-1,m-n+1);
        km();
    }

    有上下界的网络流https://www.lydsy.com/JudgeOnline/problem.php?id=2502

    #include<bits/stdc++.h>
    using namespace std;
    const int N=30100,M=500100;
    struct edge{int v,nxt,c;}e[M];
    int n,m,cnt=1,ans,S,T,hd[N],lv[N],q[N];
    void add(int u,int v,int w)
    {
        e[++cnt]=(edge){v,hd[u],w};hd[u]=cnt;
        e[++cnt]=(edge){u,hd[v],0};hd[v]=cnt;
    }
    bool bfs()
    {
        int qs=0,qe=1;
        memset(lv,0,sizeof lv);
        q[0]=0;lv[0]=1;
        while(qs<qe)
        {
            int u=q[qs++];if(u==T)break;
            for(int i=hd[u];i;i=e[i].nxt)
            if(e[i].c&&!lv[e[i].v])lv[e[i].v]=lv[u]+1,q[qe++]=e[i].v;
        }
        return lv[T];
    }
    int dfs(int u,int f)
    {
        if(u==T)return f;
        int sum=0,tmp;
        for(int i=hd[u];i;i=e[i].nxt)
        if(e[i].c&&lv[e[i].v]==lv[u]+1)
        {
            tmp=dfs(e[i].v,min(f,e[i].c));
            sum+=tmp;f-=tmp;
            e[i].c-=tmp;e[i^1].c+=tmp;
        }
        if(!sum)lv[u]=-1;
        return sum;
    }
    void solve(){while(bfs())ans+=dfs(0,1e9);}
    int main()
    {
        scanf("%d",&n);
        int x,y;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            while(x--)
            {
                scanf("%d",&y);m++;
                add(i,n+2*m-1,1e9);add(n+2*m,y,1e9);
                add(n+2*m-1,n+2*m,1e9);
            }
        }
        S=n+2*m+1;T=S+1;
        for(int i=1;i<=n;i++)add(S,i,1e9);
        for(int i=1;i<=m;i++)add(0,n+2*i,1),add(n+2*i-1,T,1);
        for(int i=1;i;i++){add(0,S,1);solve();if(ans==m){printf("%d",i);break;}}
    }

    霍尔定理https://www.lydsy.com/JudgeOnline/problem.php?id=3693

    #include<bits/stdc++.h>
    #define lson l,mid,rt*2
    #define rson mid+1,r,rt*2+1
    using namespace std;
    const int N=4e5+7;
    struct que{int l,r,a;}q[N];
    int n,m,a[N],mx[N*4],lazy[N*4];
    bool operator<(que a,que b){return a.r<b.r;}
    void build(int l,int r,int rt)
    {
        if(l==r){mx[rt]=a[l]-1;return;}
        int mid=(l+r)/2;
        build(lson);build(rson);
        mx[rt]=max(mx[rt*2],mx[rt*2+1]);
    }
    void pushdown(int rt)
    {
        if(!lazy[rt])return;
        lazy[rt*2]+=lazy[rt];mx[rt*2]+=lazy[rt];
        lazy[rt*2+1]+=lazy[rt];mx[rt*2+1]+=lazy[rt];
        lazy[rt]=0;
    }
    void add(int L,int R,int c,int l,int r,int rt)
    {
        if(L<=l&&r<=R){mx[rt]+=c;lazy[rt]+=c;return;}
        int mid=(l+r)/2;
        pushdown(rt);
        if(L<=mid)add(L,R,c,lson);
        if(R>mid)add(L,R,c,rson);
        mx[rt]=max(mx[rt*2],mx[rt*2+1]);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return mx[rt];
        pushdown(rt);
        int mid=(l+r)/2,ret=0;
        if(L<=mid)ret=max(ret,query(L,R,lson));
        if(R>mid)ret=max(ret,query(L,R,rson));
        return ret;
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            int sum=0,tot=n;
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].a);
                q[i].l++,q[i].r++;
                sum+=q[i].a;
                if(q[i].l>q[i].r)q[i].r+=m;
                else q[++tot].l=q[i].l+m,q[tot].r=q[i].r+m,q[tot].a=q[i].a;
            }
            if(sum>m){puts("No");continue;}
            n=tot;tot=0;
            for(int i=1;i<=n;i++)a[++tot]=q[i].l,a[++tot]=q[i].r;
            sort(a+1,a+tot+1);
            tot=unique(a+1,a+tot+1)-a-1;
            memset(lazy,0,sizeof lazy);
            memset(mx,0,sizeof mx);
            build(1,tot,1);
            sort(q+1,q+n+1);
            bool flag=1;
            for(int i=1;i<=n;i++)
            {
                q[i].l=lower_bound(a+1,a+tot+1,q[i].l)-a;
                q[i].r=lower_bound(a+1,a+tot+1,q[i].r)-a;
                add(1,q[i].l,q[i].a,1,tot,1);
                if(query(1,q[i].r,1,tot,1)>a[q[i].r]){flag=0;break;}
            }
            if(flag)puts("Yes");else puts("No");
        }
    }

    完结撒花

  • 相关阅读:
    辛星浅析跨域传输的CORS解决方式
    Hadoop HDFS (3) JAVA訪问HDFS
    【多线程】将大批量数据插入多张表,怎么知道多张表都插成功了
    【sublime text 3】sublime text 3 汉化
    【spring data jpa】使用spring data jpa时,关于service层一个方法中进行【删除】和【插入】两种操作在同一个事务内处理
    【spring data jpa】使用spring data jpa 的删除操作,需要加注解@Modifying @Transactional 否则报错如下: No EntityManager with actual transaction available for current thread
    【spring mvc】后台的API,测试中,总提示接口实体的某一个字段不能为null,但是明明给值了还提示不能为空
    【postman】postman测试API报错如下:TypeError: Failed to execute 'fetch' on 'Window': Invalid value 对中文支持不好
    【spring mvc】后台spring mvc接收List参数报错如下:org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface
    【java】Java transient关键字使用小记【转】
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/11039228.html
Copyright © 2011-2022 走看看