dinic 网络流算法 :
反悔边的意义:当一条流量被流入,反向流入的时候,就相当于没有流过。
分层图的意义:对于给定的点,流入< =dep[ u ] 是没有意义的,不会使得当前流更优。
当前弧优化:当前的边已经流光,不再流入。
炸点优化:当前点已经流光,设dep为-1,不再流入。
多路增广:如果一个点可以多条流出去,一次dfs多条路径。
BFS :每次建立一个分层图。
DFS:流过一条流
P3376 【模板】网络最大流
模板。
/* dinic最大流,复杂度上界O(V*V*E) 设置源点和汇点。 */ #include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e5+5; int n,m,S,T; struct Dinic{ int head[N],dep[N]; int ecnt; struct edge{ int v,flow,next; }e[N<<1]; void init(){ memset(head, -1, sizeof head); ecnt = 0; } void addedge(int u, int v, int flow) { e[ecnt].v=v;e[ecnt].flow=flow;e[ecnt].next=head[u];head[u]=ecnt++; } bool BFS(){ memset(dep,0,sizeof dep); queue<int>Q; Q.push(S);dep[S]=1; while(!Q.empty()){ int u=Q.front();Q.pop(); for(int i=head[u];~i;i=e[i].next){ if(e[i].flow&&!dep[e[i].v]){ dep[e[i].v]=dep[u]+1; Q.push(e[i].v); } } } return dep[T]; } int DFS(int u, int f){ if(u==T||f==0)return f; int w,used=0; for(int i=head[u];~i;i=e[i].next){ if(e[i].flow&&dep[e[i].v]==dep[u]+1){ w=DFS(e[i].v,min(f,e[i].flow)); e[i].flow-=w; e[i^1].flow+=w; used+=w; f-=w; } } if(!used)dep[u]=-1; return used; } int maxflow() { int ans=0; while(BFS()){ ans+=DFS(S,inf); } return ans; } }dinic; int main(){ scanf("%d %d %d %d",&n,&m,&S,&T); dinic.init(); int u,v,w; while(m--){ scanf("%d %d %d",&u,&v,&w); dinic.addedge(u,v,w); dinic.addedge(v,u,0); } printf("%d\n",dinic.maxflow()); return 0; }View Code