最大流模板成为另一个被攻克的模板题。
今天QDC给我讲了一下Dinic,感觉很好懂。于是为了巩固就把这道题A掉了。
核心思想就是不断BFS分层,然后不断DFS找增广路。找不到之后就可以把答案累加输出了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct Edge{ int next,to,val; }edge[1000010]; int head[10010],num=-1; inline void add(int from,int to,int val){ edge[++num]=(Edge){ head[from],to,val}; head[from]=num; } bool vis[10010]; int dfn[10010]; int f[100010],h,t=1; int n,m,Start,End; bool bfs(){ memset(vis,0,sizeof(vis)); f[1]=Start;vis[Start]=1;dfn[Start]=1;h=0;t=1; while(h++<t){ int from=f[h]; for(int i=head[from];i!=-1;i=edge[i].next){ int to=edge[i].to; if(vis[to]||(!edge[i].val)) continue; dfn[to]=dfn[from]+1; vis[to]=1; f[++t]=to; } } return vis[End]; } int dfs(int x,int val){ if(x==End) return val; vis[x]=1; for(int i=head[x];i!=-1;i=edge[i].next){ int to=edge[i].to; if(dfn[to]==dfn[x]+1&&!vis[to]&&edge[i].val>0){ int now=dfs(to,std::min(edge[i].val,val)); if(now>0){ edge[i].val-=now; edge[i^1].val+=now; return now; } } } } int ans; int main(){ memset(head,-1,sizeof(head)); n=read(),m=read(),Start=read(),End=read(); for(int i=1;i<=m;++i){ int from=read(),to=read(),val=read(); add(from,to,val); add(to,from,0); } while(bfs()){ memset(vis,0,sizeof(vis)); int now=dfs(Start,0x7fffffff); if(!now) break; ans+=now; } printf("%d",ans); return 0; }
我知道这么一笔带过很不友好啊……所以Sniffestherose写的一篇不错的网络流讲解博客 为什么不去看看呢?
友链出门右拐……