首页 > 代码库 > [网络流dinic]日常翻新
[网络流dinic]日常翻新
之前的排版简直辣眼睛,重写一遍好了
模板题是草地排水poj1273
网络流的基础思想就是瞎基本搜
但是搜要搜得有技巧,有特色
最简单的搜,无限深搜直到终点
稍微改进一下,宽搜先标号然后按层搜
再改进一下,把某些确定不再使用的点剔除
要点在于建立反向边给自己一个反悔的机会,用^1找到反向边
#include <stdio.h> #include <queue> #include <algorithm> #include <string.h> using namespace std; const int N=205; const int M=405; int m,n,s,last[N],level[N]; struct edge { int v,w,n; }e[M]; void add(int u,int v,int w) { e[s]=(edge){v,w,last[u]},last[u]=s++; e[s]=(edge){u,0,last[v]},last[v]=s++; } int BFS() { memset(level,-1,sizeof(level)); queue<int>q; q.push(1);level[1]=0; while(!q.empty()) { int t=q.front();q.pop(); for (int i=last[t];~i;i=e[i].n) { if(e[i].w&&level[e[i].v]==-1) q.push(e[i].v),level[e[i].v]=level[t]+1; } } return level[n]!=-1; } int DFS(int a,int b) { if (a==n) return b; int r=0; for (int i=last[a];~i&&b>r;i=e[i].n) { if (level[a]+1==level[e[i].v]&&e[i].w) { int t=DFS(e[i].v,min(b-r,e[i].w)); e[i].w-=t;e[i^1].w+=t;r+=t; } } if (!r) level[a]=-1; return r; } int dinic() { int ans=0,tmp; while(BFS())while(tmp=DFS(1,0x3fffffff))ans+=tmp; return ans; } int main() { while(scanf ("%d %d",&m,&n)!=EOF) { memset (last,-1,sizeof(last)); s=0; for (int i=1;i<=m;i++) { int u,v,w; scanf ("%d %d %d",&u,&v,&w); add(u,v,w); //add(v,u,0); } printf ("%d\n",dinic()); } }
就是这样,喵~
最后一行献给可爱的男孩子们
[网络流dinic]日常翻新
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。