标签:
POJ 1273
给出M条边,N个点,求源点1到汇点N的最大流量。
本文主要就是附上dinic的模板,供以后参考。
#include <iostream> #include <stdio.h> #include <algorithm> #include <queue> #include <string.h> /* POJ 1273 dinic算法模板 边是有向的,而且存在重边,且这里重边不是取MAX,而是累加和 */ using namespace std; const int INF=0x3f3f3f3f; const int maxn=201; int pri[maxn]; long long sum; //计算总流量 int s,t; //s:源点 t:汇点 int n,m; struct Edge{ int c,f; }maps[maxn][maxn]; int min(int a,int b){ return a<b?a:b; } //每次先BFS,看看是否存在从源点到汇点的增广路 bool BFS() { queue<int> q; memset(pri,0,sizeof(pri)); pri[1]=1; q.push(1); while(!q.empty()) { int temp=q.front(); q.pop(); for(int i=1; i<=m; i++) { if(!pri[i] && maps[temp][i].c-maps[temp][i].f){ pri[i]=pri[temp]+1; if(i==t) return true; //即如果可以流到汇点,直接return true q.push(i); } } } //if(pri[m]>0) // return true; return false; } //p表示当前节点,flow表示该节点通过的流量 int dinic(int p,int flow){ if(p==t){ return flow; } int f=flow; //int value=0; for(int i=1;i<=m;i++){ if(pri[i]==pri[p]+1 && maps[p][i].c-maps[p][i].f){ int a=maps[p][i].c-maps[p][i].f; //a为该边可以增加的流量 int ff=dinic(i,min(a,flow)); //ff为路径中所有a的最小值,即为该条路中可以增加的流量 maps[p][i].f+=ff; //正向边 maps[i][p].f-=ff; //逆向边 //value+=ff; flow-=ff; if(flow<=0) break; //优化剪枝 } } //return value; if(f-flow<=0) pri[p]=0;//如果从p点流出去的流量<=0,那么设置pri[p]的值为0,之后在dinic中就不考虑到p点的情况了。 return f-flow; } void init(){ for(int i=1;i<=m;i++){ for(int j=1;j<=m;j++){ maps[i][j].c=maps[i][j].f=0; } } } int main() { int a,b,c; s=1; while(scanf("%d%d",&n,&m)!=EOF){ init(); //memset(maps,0,sizeof(maps)); sum=0; t=m; for(int i=1;i<=n;i++){ scanf("%d%d%d",&a,&b,&c); maps[a][b].c+=c; //该题有重边,这里要+=,不是去max } while(BFS()){ sum+=dinic(s,INF); } printf("%I64d\n",sum); } return 0; }
再给出一个大牛的模板:
#include <cstdio> #include <queue> using namespace std; typedef int LL; const int N = 205; const int M = N << 2; const int INF = (int)1e9; struct Dinic { struct Edge { int v; LL cap, flow; Edge* next, * pair; void init(int a, LL b, Edge* e1, Edge* e2) { v = a, cap = b, flow = 0, next = e1, pair = e2; } }; Edge* head[N], * used[N]; Edge* it; int lev[N], que[N]; Edge E[M]; int n, s, t; LL maxFlow; void init(int n, int s, int t) { it = E; this->n = n; this->s = s, this->t = t; for (int i = 0; i < n; i++) head[i] = 0; } void add(int u, int v, LL c) { it->init(v, c, head[u], it + 1); head[u] = it++; it->init(u, 0, head[v], it - 1); head[v] = it++; } bool bfs() { for (int i = 0; i < n; lev[i++] = -1); lev[s] = 0; int st = 0, ed = 0; que[ed++] = s; while (st < ed) { int u = que[st++]; for (Edge* e = head[u]; e; e = e->next) { int v = e->v; if (lev[v] == -1 && e->cap > e->flow) { lev[v] = lev[u] + 1; que[ed++] = v; } } } return lev[t] != -1; } LL dfs(int u, LL f) { if (u == t) return f; for (Edge* & e = used[u]; e; e = e->next) { int v = e->v; if (e->cap > e->flow && lev[v] == lev[u] + 1) { LL tmp = dfs(v, min(e->cap - e->flow, f)); if (tmp > 0) { e->flow += tmp; e->pair->flow -= tmp; return tmp; } } } return 0; } void run() { maxFlow = 0; while (bfs()) { for (int i = 0; i < n; i++) used[i] = head[i]; LL f = 1; while (f) { f = dfs(s, INF); maxFlow += f; } } } }G; int main() { int n, m, u, v, w; while (~scanf("%d%d", &m, &n)) { G.init(n, 0, n - 1); while (m--) { scanf("%d%d%d", &u, &v, &w); G.add(u - 1, v - 1, w); } G.run(); printf("%d\n", G.maxFlow); } return 0; }
POJ 1273 Drainage Ditches(网络流dinic算法模板)
标签:
原文地址:http://www.cnblogs.com/chenxiwenruo/p/4513810.html