1.初始网络流,最大流模型p3376P2740
#include <stdio.h> #include <algorithm> #include <cstring> #define INF 100000000 using namespace std; typedef long long ll; const int maxn=2000000; int head[maxn],next[maxn],ver[maxn],tot; int cur[maxn],lev[maxn]; ll wei[maxn];//本题模板提,数据范围要注意一下 int n,m,sou,des; inline void add(int x,int y,int w) { ver[++tot]=y;wei[tot]=w;next[tot]=head[x];head[x]=tot; ver[++tot]=x;wei[tot]=0;next[tot]=head[y];head[y]=tot; } inline ll dinic(int x,ll flow) { if(x==des) return flow; ll v,res=0,delta; for(int i=cur[x];i;i=next[i]) { if(wei[i]>0&&lev[x]<lev[v=ver[i]])//按照这种方法的分层图构建的话,lev[x]<lev[v]就是可以遍历的,否则就会爆炸 { delta=dinic(v,min(wei[i],flow-res)); if(delta) { wei[i]-=delta;wei[i^1]+=delta; res+=delta;if(res==flow) break; } } } if(res!=flow) lev[x]=-1; return res; } inline bool bfs() { static int que[202],ql=1,qr=1; int x,v; for(int i=1;i<=n;i++) lev[i]=-1,cur[i]=head[i]; que[ql]=sou;lev[sou]=0; for(ql=1,qr=1;ql<=qr;ql++) { x=que[ql]; for(int i=head[x];i;i=next[i]) { //printf("%d %d\n",x,ver[i]); if(wei[i]>0&&lev[v=ver[i]]==-1) { lev[v]=lev[x]+1; que[++qr]=v; if(v==des) return true; } } } return false; } inline ll maxflow() { ll ans=0; while(bfs()) ans+=dinic(sou,INF); return ans; } int main() { scanf("%d%d%d%d",&n,&m,&sou,&des); tot=1; for(int i=1;i<=m;i++) { int u,v;ll w; scanf("%d%d%lld",&u,&v,&w); add(u,v,w); } printf("%lld",maxflow()); return 0; }
注意前向弧优化和关于关于分层图的构建
原文:https://www.cnblogs.com/ILHYJ/p/13617056.html