• 上下界网络流总结


    $orz$ $zhhx$

    $orz$ $yyb$

    $orz$ $AYSN$

    无源汇可行流:每条边取$L[i] + $最大流调整

    有源汇可行流:$E + (T,S,INF) + $无源汇可行流

    有源汇最小流:有源汇可行流(去掉$INF$边)$- T ightarrow S$最大流

    有源汇最大流:有源汇可行流(去掉$INF$边)$+ S ightarrow T$最大流

    上下界网络流,不过于此。


    有源汇最小流

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<cstdlib>
    #define LL long long
    #define N 50005
    #define M 150005
    #define INF 1000000000000007LL
    #define ri register int
    using namespace std;
    
    int n,m,s,t;
    int u[M],v[M],l[M],r[M];
    LL p[N];
    
    struct graph {
      vector<int> to,ed[N];
      vector<LL> w;
      int cur[N],d[N];
      int S,T;
      void add_edge(int u,int v,LL w1) {
        to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(0);  ed[v].push_back(to.size()-1);
      }
      void add_edges(int u,int v,LL w1,LL w2) {
        to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(w2); ed[v].push_back(to.size()-1);
      }
      bool bfs() {
        queue<int> q;
        memset(d,0x3f,sizeof(d));
        d[S]=0; q.push(S);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0,l=ed[x].size();i<l;i++) {
            int e=ed[x][i];
            if (w[e] && d[x]+1<d[to[e]]) {
              d[to[e]]=d[x]+1;
              q.push(to[e]);
            }
          }
        }
        return d[T]<1000000007;
      }
      LL dfs(int x,LL limit) {
        if (x==T || !limit) return limit;
        LL tot=0;
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (d[to[e]]==d[x]+1 && w[e]) {
            LL f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            w[e]-=f; w[1^e]+=f; 
            tot+=f; limit-=f;
            if (!limit) return tot;
          }
        }
        return tot;
      }
      LL dinic() {
        LL ret=0;
        while (bfs()) {
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF);
        }
        return ret;
      }
    } G,G2;
    
    int main() {
      scanf("%d %d %d %d",&n,&m,&s,&t);
      for (ri i=1;i<=m;i++) {
        scanf("%d %d %d %d",&u[i],&v[i],&l[i],&r[i]);
        p[u[i]]-=l[i],p[v[i]]+=l[i];
      }
      LL sum=0;
      for (ri i=1;i<=m;i++) G2.add_edge(u[i],v[i],r[i]-l[i]);
      for (ri i=1;i<=n;i++) {
        if (p[i]>0) sum+=p[i],G2.add_edge(0,i,p[i]);
        else if (p[i]<0) G2.add_edge(i,n+1,-p[i]);
      }
      G2.add_edge(t,s,INF);
      G2.S=0; G2.T=n+1;
      if (G2.dinic()<sum) {
        puts("please go home to sleep");
        return 0;
      }
      LL flow1=G2.w[G2.w.size()-1];
      for (ri i=1;i<=n;i++) {
        for (ri j=0;j<G2.ed[i].size();j++) {
          int e=G2.ed[i][j];
          if (e%2==0&&0<=e/2&&e/2<m) G.add_edges(i,G2.to[e],G2.w[e],r[e/2+1]-l[e/2+1]-G2.w[e]);
        }
      }
      G.S=t; G.T=s;
      cout<<flow1-G.dinic()<<endl;
      return 0;
    }

    有源汇最大流

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<cstdlib>
    #define LL long long
    #define N 50005
    #define M 150005
    #define INF 1000000000000007LL
    #define ri register int
    using namespace std;
    
    int n,m,s,t;
    int u[M],v[M],l[M],r[M];
    LL p[N];
    
    struct graph {
      vector<int> to,ed[N];
      vector<LL> w;
      int cur[N],d[N];
      int S,T;
      void add_edge(int u,int v,LL w1) {
        to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(0);  ed[v].push_back(to.size()-1);
      }
      void add_edges(int u,int v,LL w1,LL w2) {
        to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(w2); ed[v].push_back(to.size()-1);
      }
      bool bfs() {
        queue<int> q;
        memset(d,0x3f,sizeof(d));
        d[S]=0; q.push(S);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0,l=ed[x].size();i<l;i++) {
            int e=ed[x][i];
            if (w[e] && d[x]+1<d[to[e]]) {
              d[to[e]]=d[x]+1;
              q.push(to[e]);
            }
          }
        }
        return d[T]<1000000007;
      }
      LL dfs(int x,LL limit) {
        if (x==T || !limit) return limit;
        LL tot=0;
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (d[to[e]]==d[x]+1 && w[e]) {
            LL f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            w[e]-=f; w[1^e]+=f; 
            tot+=f; limit-=f;
            if (!limit) return tot;
          }
        }
        return tot;
      }
      LL dinic() {
        LL ret=0;
        while (bfs()) {
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF);
        }
        return ret;
      }
    } G,G2;
    
    int main() {
      scanf("%d %d %d %d",&n,&m,&s,&t);
      for (ri i=1;i<=m;i++) {
        scanf("%d %d %d %d",&u[i],&v[i],&l[i],&r[i]);
        p[u[i]]-=l[i],p[v[i]]+=l[i];
      }
      LL sum=0;
      for (ri i=1;i<=m;i++) G2.add_edge(u[i],v[i],r[i]-l[i]);
      for (ri i=1;i<=n;i++) {
        if (p[i]>0) sum+=p[i],G2.add_edge(0,i,p[i]);
        else if (p[i]<0) G2.add_edge(i,n+1,-p[i]);
      }
      G2.add_edge(t,s,INF);
      G2.S=0; G2.T=n+1;
      if (G2.dinic()<sum) {
        puts("please go home to sleep");
        return 0;
      }
      LL flow1=G2.w[G2.w.size()-1];
      for (ri i=1;i<=n;i++) {
        for (ri j=0;j<G2.ed[i].size();j++) {
          int e=G2.ed[i][j];
          if (e%2==0&&0<=e/2&&e/2<m) G.add_edges(i,G2.to[e],G2.w[e],r[e/2+1]-l[e/2+1]-G2.w[e]);
        }
      }
      G.S=s; G.T=t;
      cout<<flow1+G.dinic()<<endl;
      return 0;
    }
  • 相关阅读:
    如何在 Linux 虚拟机上扩展根文件系统
    Linux 虚拟机中配置 GNOME + VNC
    在 Linux 中使用 Azure Premium 存储的基本优化指南
    如何为运行的 ARM Linux 启用 LAD2.3 版本的诊断扩展
    不要在构造函数中抛出异常
    vtk java
    富文本keditor的一些使用问题
    几个问题
    Java并发编程(十四)并发容器类
    FreeBSD编译安装emacs,不要用ports
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11218919.html
Copyright © 2020-2023  润新知