P3376 【模板】网络最大流

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<bitset>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define precision(x,d) cout<<fixed<<setprecision(d)<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e5+5;
int n,m;

const int MAXN = 1e4+105;
const int MAXE = 4e5+7;
struct lp {
    int v,nex;
    int cap,flow;
} cw[MAXE];
int vs,vt,NE,NV;
int head[MAXN],pre[MAXN],cur[MAXN],level[MAXN],gap[MAXN];
inline void add_edge(int u,int v,int cap){
  cw[NE].v = v;cw[NE].cap = cap;cw[NE].flow = 0;cw[NE].nex = head[u];
  head[u] = NE++;
  cur[u] = head[u];
  cw[NE].v = u;cw[NE].cap = 0;cw[NE].flow = 0;cw[NE].nex = head[v];
  head[v] = NE++;
  cur[v] = head[v];
}
inline void bfs(int vt){
    memset(level,-1,sizeof(level));
    memset(gap,0,sizeof(gap));
    level[vt]=0;
    gap[level[vt]]++;
    queue<int>que;
    que.push(vt);
    while(!que.empty()) {
        int u=que.front();
        que.pop();
        for(int i=head[u]; i!=-1; i=cw[i].nex) {
            int v=cw[i].v;
            if(level[v]!=-1)continue;
            level[v]=level[u]+1;
            gap[level[v]]++;
            que.push(v);
        }
    }
}
int SAP(int vs,int vt){
    bfs(vt);
    memset(pre,-1,sizeof(pre));
    //for(int i=0;i<=n;++i)cur[i]=head[i];
    int u=pre[vs]=vs,flow=0,aug=INF;
    gap[0]=NV;
    while(level[vs]<NV) {
        bool flag=false;
        for(int &i=cur[u]; i!=-1; i=cw[i].nex) {
            int v=cw[i].v;
            if(cw[i].cap>cw[i].flow&&level[u]==level[v]+1) {
                flag=true;
                pre[v]=u;
                u=v;
                //  aug=(aug==-1?cw[i].cap:min(aug,cw[i].cap));
                aug=min(aug,cw[i].cap-cw[i].flow );
                if(v==vt) {
                    flow+=aug;
                    for(u=pre[v]; v!=vs; v=u,u=pre[u]) {
                        cw[cur[u]].flow+=aug;
                        cw[cur[u]^1].flow-=aug;
                    }
                    //     aug=-1;
                    aug=INF;
                }
                break;
            }
        }
        if(flag)continue;
        int minlevel=NV;
        for(int i=head[u]; i!=-1; i=cw[i].nex) {
            int v=cw[i].v;
            if(cw[i].cap>cw[i].flow&&level[v]<minlevel) {
                minlevel=level[v];
                cur[u]=i;
            }
        }
        if(--gap[level[u]]==0)break;
        level[u]=minlevel+1;
        gap[level[u]]++;
        u=pre[u];
    }
    return flow;
}
void init(){
    NE=0;NV=n;
    //vs=1;vt=n;
    memset(head,-1,sizeof(head));
    memset(cur,-1,sizeof(cur));
}

int main(){
    int u,v,w;
    scanf("%d%d%d%d",&n,&m,&vs,&vt);
    init();
    for(int i=1; i<=m; i++) {
        scanf("%d%d%d",&u,&v,&w);
        add_edge(u,v,w);
    }
    printf("%d\n",SAP(vs,vt));
    return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<bitset>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define precision(x,d) cout<<fixed<<setprecision(d)<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;

const int INF = 0x3f3f3f3f;
const int MXN = 1e4+7;
const int MXE = 4e5+7;
int vs, vt;
struct DINIC{
  int tot,vt,vs;
  int d[MXN],head[MXN];
  struct lp{
    int v,w,nex;
  }cw[MXE];
  void add_edge(int a,int b,int c){
    cw[++tot].v=b;cw[tot].nex=head[a],cw[tot].w=c;
    head[a]=tot;
    cw[++tot].v=a;cw[tot].nex=head[b],cw[tot].w=0;
    head[b]=tot;
  }
  bool bfs(){
    memset(d,-1,sizeof(d));
    queue<int>Q;
    Q.push(vt);d[vt]=0;
    while(!Q.empty()){
      int u=Q.front();
      Q.pop();
      for(int i=head[u];i!=-1;i=cw[i].nex){
        int v=cw[i].v;
        if(cw[i^1].w&&d[v]==-1){
          d[v]=d[u]+1;
          Q.push(v);
        }
      }
    }
    return d[vs]!=-1;
  }
  /*int dfs(int x,int low){
    if(x==vt||low==0)return low;
    int flow=0,used=0;
    for(int i=head[x];i!=-1;i=cw[i].nex){
      int v=cw[i].to;
      if(cw[i].w&&d[v]+1==d[x]&&(used=dfs(v,min(low,cw[i].w)))>0){
        //used=dfs(v,min(low,cw[i].w));
        if(!used)continue;
        flow+=used,low-=used;
        cw[i].w-=used;cw[i^1].w+=used;
        if(!low)break;
      }
    }
    if(!flow)d[x]=-1;
    return flow;
  }*/
  int dfs(int x,int f){
    if(x==vt||f==0) return f;
    int use=0,w;
    for(int i=head[x];i!=-1;i=cw[i].nex){
      int to=cw[i].v;
      if(d[to]==d[x]-1 && cw[i].w){
        w=dfs(to,min(cw[i].w,f-use));
        cw[i].w-=w,cw[i^1].w+=w;
        use+=w;
        if(use==f) return f;
      }
    }
    if(!use)d[x]=-1;
    return use;
  }
  void init(int st,int ed){
    tot=-1;
    memset(head,-1,sizeof(head));
    vs=st;vt=ed;
  }
  int max_flow(){
    int ans=0;
    while(bfs())ans+=dfs(vs,INF);
    return ans;
  }
}dinic;


int main(){
    int u,v,w,n,m;
    scanf("%d%d%d%d",&n,&m,&vs,&vt);
    dinic.init(vs,vt);
    for(int i=1; i<=m; i++) {
        scanf("%d%d%d",&u,&v,&w);
        dinic.add_edge(u,v,w);
    }
    printf("%d\n",dinic.max_flow());
    return 0;
}
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf = 0x3fffffff;
template <int N, int M>
struct Isap{
    int top;
    int d[N], pre[N], cur[N], gap[N];
    struct Vertex {
        int head;
    } V[N];
    struct Edge {
        int v, next;
        int c, f;
    } E[M];
    void init() {
        memset(V, -1, sizeof(V));
        top = 0;
    }
    void add_edge(int u, int v, int c) {
        E[top].v = v;
        E[top].c = c;
        E[top].f = 0;
        E[top].next = V[u].head;
        V[u].head = top++;
    }
    void add(int u, int v, int c) {
        add_edge(u, v, c);
        add_edge(v, u, 0);
    }
    void set_d(int t) {
        queue<int> Q;
        memset(d, -1, sizeof(d));
        memset(gap, 0, sizeof(gap));
        d[t] = 0;
        Q.push(t);
        while (!Q.empty()) {
            int v = Q.front(); Q.pop();
            ++gap[d[v]];
            for (int i = V[v].head; ~i; i = E[i].next) {
                int u = E[i].v;
                if (d[u] == -1) {
                    d[u] = d[v] + 1;
                    Q.push(u);
                }
            }
        }
    }
    int sap(int s, int t, int num) {
        set_d(t);
        int ans = 0, u = s;
        int flow = inf;
        memcpy(cur, V, sizeof(V));
        while (d[s] < num) {
            int &i = cur[u];
            for (; ~i; i = E[i].next) {
                int v = E[i].v;
                if (E[i].c > E[i].f && d[u] == d[v] + 1) {
                    u = v;
                    pre[v] = i;
                    flow = min(flow, E[i].c - E[i].f);
                    if (u == t) {
                        while (u != s) {
                            int j = pre[u];
                            E[j].f += flow;
                            E[j ^ 1].f -= flow;
                            u = E[j ^ 1].v;
                        }
                        ans += flow;
                        flow = inf;
                    }
                    break;
                }
            }
            if (i == -1) {
                if (--gap[d[u]] == 0)
                    break;
                int dmin = num - 1;
                cur[u] = V[u].head;
                for (int j = V[u].head; ~j; j = E[j].next)
                    if (E[j].c > E[j].f)
                        dmin = min(dmin, d[E[j].v]);
                d[u] = dmin + 1;
                ++gap[d[u]];
                if (u != s)
                    u = E[pre[u] ^ 1].v;
            }
        }
        return ans;
    }
};
Isap<200005, 400005> Sap;
int tux[100001], tuy[100001],st,zt;
int main(){
    int n, m;
    scanf("%d%d%d%d", &n, &m, &st, &zt);
    int q, w, e;
    Sap.init();
    for (int a = 1; a <= m; a++){
        scanf("%d%d%d", &q, &w, &e);
        Sap.add(q, w, e);
    }
    printf("%d\n",Sap.sap(st, zt, 9 * m + 2));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Cwolf9/p/10181669.html