网络流三种算法及比较
2016-08-25 18:23
288 查看
核心代码
(1)EK 算法
复杂度O(V*E*E)
(2)Dinic递归
(3)SAP算法
(1)EK 算法
复杂度O(V*E*E)
#define N 204 int c ;//边容量 int f ;//边实际流量 int pre ;//记录增广路径 int res ;//残余网络 queue<int> qq; void init(){ while(!qq.empty())qq.pop(); memset(c,0,sizeof(c)); memset(f,0,sizeof(f)); } int EK(int s,int t){ int i,j; int ans=0; while(1){ memset(res,0,sizeof(res)); res[s] = MAX;//源点的残留网络要置为无限大!否则下面找增广路出错 pre[s] = -1; qq.push(s); //bfs找增广路径 while(!qq.empty()){ int x = qq.front(); qq.pop(); for(i=1;i<=t;i++){ if(!res[i] && f[x][i] < c[x][i]){ qq.push(i); pre[i] = x; res[i] = min(c[x][i] - f[x][i], res[x]);//这里类似dp,如果有增广路,那么res[t]就是增广路的最小权 } } } if(res[t]==0)break;//找不到增广路就退出 int k = t; while(pre[k]!=-1){ f[pre[k]][k] += res[t];//正向边加上新的流量 f[k][pre[k]] -= res[t];//反向边要减去新的流量,反向边的作用是给程序一个后悔的机会 k = pre[k]; } ans += res[t]; } return ans; }
(2)Dinic递归
#define M 400 struct node { int u, v, next, cap; } edge[M*M]; int next[M], head[M], layer[M], Q[M * 2], mark[M]; int ecnt; void init(){ ecnt= 0; memset(head,-1,sizeof(head)); } void add(int u, int v, int c) { edge[ecnt].u = u; edge[ecnt].v = v; edge[ecnt].cap = c; edge[ecnt].next = head[u]; head[u] = ecnt++; edge[ecnt].u = v; edge[ecnt].v = u; edge[ecnt].cap = 0; edge[ecnt].next = head[v]; head[v] = ecnt++; } bool BFS(int begin, int end) { int i, l, h, k, y; for (i = 0; i <= end; i++) layer[i] = -1; layer[begin] = 0; l = h = 0; Q[l++] = begin; while (h < l) { k = Q[h++]; for (i = head[k]; i != -1; i = edge[i].next) { y = edge[i].v; if (edge[i].cap > 0 && layer[y] == -1) { layer[y] = layer[k] + 1; if (y == end) return true; Q[l++] = y; } } } return false; } int DFS(int x, int exp, int end) { mark[x] = 1; if (x == end)return exp; int y, temp, i; for (i = next[x]; i != -1; i = edge[i].next, next[x] = i) { y = edge[i].v; if (edge[i].cap > 0 && layer[y] == layer[x] + 1 && !mark[y]) { if ((temp = (DFS(y, min(exp, edge[i].cap), end))) > 0) { edge[i].cap -= temp;//流完后正向流表示剩余流量 edge[i^1].cap += temp;//流完后反向流表示正向流的流量 return temp; } } } return 0; } int Dinic_flow(int begin, int end) { int i, ans = 0, flow; while (BFS(begin, end)) { for (i = 0; i <= end; i++)next[i] = head[i]; while (true) { for (i = 0; i <= end; i++) mark[i] = 0; flow = DFS(begin, INT_MAX, end); if (flow == 0)break; ans += flow; } } return ans; }
(3)SAP算法
const int MAXN=20010; const int MAXM=500010; int n,m;//n为点数 m为边数 int h[MAXN]; int gap[MAXN]; int p[MAXN],ecnt; int source,sink; struct edge{ int v;//边的下一点 int next;//下一条边的编号 int val;//边权值 }e[MAXM]; inline void init(){memset(p,-1,sizeof(p));eid=0; //有向 inline void insert1(int from,int to,int val){ e[ecnt].v=to; e[ecnt].val=val; e[ecnt].next=p[from]; p[from]=eid++; swap(from,to); e[ecnt].v=to; e[ecnt].val=0; e[ecnt].next=p[from]; p[from]=eid++; } //无向 inline void insert2(int from,int to,int val){ e[ecnt].v=to; e[ecnt].val=val; e[ecnt].next=p[from]; p[from]=eid++; swap(from,to); e[ecnt].v=to; e[ecnt].val=val; e[ecnt].next=p[from]; p[from]=eid++; } inline int dfs(int pos,int cost){ if (pos==sink){ return cost; } int j,minh=n-1,lv=cost,d; for (j=p[pos];j!=-1;j=e[j].next){ int v=e[j].v,val=e[j].val; if(val>0){ if (h[v]+1==h[pos]){ if (lv<e[j].val) d=lv; else d=e[j].val; d=dfs(v,d); e[j].val-=d; e[j^1].val+=d; lv-=d; if (h[source]>=n) return cost-lv; if (lv==0) break; } if (h[v]<minh) minh=h[v]; } } if (lv==cost){ --gap[h[pos]]; if (gap[h[pos]]==0) h[source]=n; h[pos]=minh+1; ++gap[h[pos]]; } return cost-lv; } int sap(int st,int ed){ source=st; sink=ed; int ans=0; memset(gap,0,sizeof(gap)); memset(h,0,sizeof(h)); gap[st]=n; while (h[st]<n){ ans+=dfs(st,INT_MAX); } return ans; }
相关文章推荐
- 爱因斯坦谜题解答(三种算法比较)
- 爱因斯坦谜题解答(三种算法比较)
- BM、GC、SGBM三种算法的比较和BM在OpenCV3下的参数设置
- BM、GC、SGBM三种算法的比较和BM在OpenCV3下的参数设置
- 十进制转bcd三种算法的比较
- Opencv中三种立体匹配算法的比较
- HDOJ--1869--六度分离(用三种算法写的,希望能比较出来他们之间的区别)
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 习题2.8 随机数组的三种生成算法(补) 将bash的实现翻译成比较纯正的bash风格
- [zz]三种模式匹配算法(KMP,MonteCarlo,LasVegas)的比较与分析
- 三种中文分词算法优劣比较
- SURF SIFT ORB三种特征检测算法比较
- WV.55-三种求最大公约数算法比较-连续整数检测法- 欧几里得算法-分解质因数算法
- 爱因斯坦谜题解答(三种算法比较)
- 费波纳切(Fibonacci)数列的前N项和公式(PHP版)三种算法的比较
- Java基础三种常见交换算法的比较
- 机器学习自学之路-SVM 算法选择:三种算法优缺点比较(ID3、C4.5、CART)
- 快速排序、归并排序、堆排序三种算法性能比较
- HDU 3657 Game (SAP | Dinic | EK 三种算法的比较)
- 三种中文分词算法优劣比较
- 爱因斯坦谜题解答(三种算法比较)