网络流dinic ek模板 poj1273
这里只是用来存放模板,几乎没有讲解,要看讲解网上应该很多吧……
ek
bfs不停寻找增广路到找不到为止,找到终点时用pre回溯,O(VE^2)
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 205; int cap[205][205], pre[205], n, m, a[205]; int bfs(){ queue<int> q; q.push(1); memset(a,0,sizeof(a)); a[1] = INF; while(!q.empty()){ int front = q.front(); q.pop(); for(int i = 1;i<=m;i++){ if(!a[i] && cap[front][i]){ a[i] = min(a[front], cap[front][i]); pre[i] = front; q.push(i); } } } return a[m]; } int ek(){ int ans = 0; while(bfs()){ ans += a[m]; for(int i = m;i!=1;i = pre[i]){ cap[pre[i]][i] -= a[m]; cap[i][pre[i]] += a[m]; } } return ans; } int main(){ while(~scanf("%d%d",&n,&m)){ memset(cap,0,sizeof(cap)); for(int i = 1;i<=n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); cap[u][v] += w; } printf("%d\n",ek()); } return 0; }
dinic
反复构造层次网络加找增广路,优势在于当某点的流入量较大时,可以一次完成多条增广路的累加,O(V^2E)
记得初始化lv,cnt=1
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int maxn = 205; const int INF = 0x3f3f3f3f; struct EDGE{ int to, next, cap, flow; EDGE(){} EDGE(int a, int b, int c, int d){ to = a, next = b, cap = c, flow = d;; } }e[410]; int head[205], cnt, lv[205],m ,n; void add(int from, int to, int cap){ e[++cnt] = EDGE(to, head[from], cap, 0); head[from] = cnt; e[++cnt] = EDGE(from, head[to], 0, 0); head[to] = cnt; } int bfs(){ queue<int> q; q.push(1); memset(lv,0,sizeof(lv)); lv[1] = 1; while(!q.empty()){ int front = q.front(); q.pop(); for(int i = head[front];i;i = e[i].next){ int to = e[i].to; if(!lv[to] && e[i].cap-e[i].flow){ lv[to] = lv[front]+1; q.push(to); } } } return lv[m]; } int dfs(int now, int a){ int flow = 0,f; if(now == m) return a; for(int i = head[now];i;i = e[i].next){ int to = e[i].to; if(lv[to] == lv[now]+1 && (f = dfs(to,min(a,e[i].cap-e[i].flow)))){ e[i].flow += f; e[i^1].flow -= f; flow += f; a -= f; if(!a) break; } } return flow; } int dinic(){ int ans = 0; while(bfs()){ ans += dfs(1,INF); } return ans; } int main(){ while(~scanf("%d%d",&n,&m)){ cnt = 1; memset(head,0,sizeof(head)); for(int i = 1;i<=n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } printf("%d\n",dinic()); } return 0; }