网络流之最大流sap算法
来源:互联网 发布:文明5mac版汉化 编辑:程序博客网 时间:2024/05/17 08:41
sap算法用于求网络流的最大流
算法框架:
1.给每个点标高度 只有高处的水才能往地处流 一开始的高度都为0
2.在所有的可行弧中不断的寻找增广路 可行弧的定义为 {(i,j) | h[i]=h[j]+1}
3.遍历完当前节点后(流不出去了) 重新标记当前点的高度(保证下次再来的时候有路可走) h[i]=min(h[j])+1;
4.检查是否存在断层 如果出现断层 则图中已不存在增广路 算法可以结束 否则从源点开始继续遍历
下面的代码的题目是 usaco 4.2.1 草地排水
/*PROG:ditchLANG:C++*/#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;#define bug cout<<"bug"<<endl;const int maxn = 300;const int inf = 123456789;int s, t;int g[maxn][maxn];int h[maxn], vh[maxn];//h个点的高度 vh各个高度点的数量int n, m;int aug(int k, int fn){ if (k == t) return fn;//到大汇点 返回 int left = fn, delta = 0; int minh = n - 1;//注意这里 是n-1 for (int i = 1; i <= n; i++) if (g[k][i] > 0) { if (h[k] == h[i] + 1) { delta = aug(i, min(left, g[k][i])); g[k][i] -= delta; g[i][k] += delta; left -= delta; if (left == 0 || h[s] == n) return fn - left;//这两个一定要加 } minh = min(minh, h[i]); } if (left == fn)//出不去就升高自己的高度 { vh[h[k]]--; if (vh[h[k]] == 0) h[s] = n;//出现断层了 gap优化 h[k] = minh + 1; vh[h[k]]++; } return fn - left;}int sap(){ int ans = 0; vh[0] = n; while (h[s] < n) ans += aug(s, inf); return ans;}int main(){ freopen("ditch.in", "r", stdin); freopen("ditch.out", "w", stdout); cin >> m >> n; int a, b, c; for (int i = 1; i <= m; i++) { cin >> a >> b >> c; g[a][b] += c; } s = 1, t = n; cout << sap() << endl; fclose(stdin); fclose(stdout); return 0;}
这里是用邻接表写的
/*PROG:ditchLANG:C++*/#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;struct node{ int d, w; node *next, *op;//op为反向边的地址};const int maxn = 300;const int inf = 123456789;node *adj[maxn];int h[maxn], vh[maxn];int n, m;//n个点 m条边int s, t;//源点和汇点void edge(int a, int b, int c){ node *p = new node, *q = new node; //正向边 和 反向边 p->d = b; p->w = c; p->next = adj[a]; adj[a] = p; q->d = a; q->w = 0;//这里要注意 反向边流量为0 q->next = adj[b]; adj[b] = q; p->op = q; q->op = p;}int aug(int k, int fm){ if(k == t) return fm; int left = fm, delta = 0; int minh = n-1; for(node *p = adj[k]; p != NULL; p = p->next) if(p->w > 0) { if(h[k] == h[p->d] + 1) { delta = aug(p->d, min(left, p->w)); p->w -= delta; p->op->w += delta; left -= delta; if(left == 0 || h[s] == n) return fm - left; } minh = min(minh, h[p->d]); } if(fm == left) { vh[h[k]]--; if(vh[h[k]] == 0) h[s] = n; h[k] = minh + 1; vh[h[k]]++; } return fm - left;}int sap(){ int ans = 0; memset(h, 0, sizeof(h)); memset(vh, 0, sizeof(vh)); vh[0] = n; while(h[s] < n) ans += aug(s, inf); return ans;}int main(){ freopen("ditch.in", "r", stdin); freopen("ditch.out", "w", stdout); cin >> m >> n; int a, b, c; for(int i = 1; i <= m; i++) { cin >> a >> b >> c; edge(a, b, c); } s = 1, t = n; cout << sap() << endl; fclose(stdin); fclose(stdout); return 0;}
- 网络流之最大流sap算法
- 网络最大流SAP算法
- 网络流最大流之SAP算法 详解
- 网络流最大流的sap()算法
- 网络流最大流sap算法模板
- [转载]网络最大流SAP算法心得
- 网络流之SAP算法
- 网络流之sap算法
- 最大流SAP算法
- 最大流SAP算法
- 最大流SAP算法
- 最大流-SAP算法
- 图论算法----网络流----最大流sap算法
- 网络流 最大流—最小割 之SAP算法 详解
- hdu3549(网络流入门题-最大流的sap算法)
- 网络流之SAP算法学习
- 网络流之SAP算法学习
- 网络流之SAP算法学习
- oracle10g 裸设备建库
- Linux 的安装配置XAMPP
- 配置dataguard (oracle10g)
- RUBY学习笔记二:使用RUBY实现通过PROXY的方式请求网页
- 冒泡发排序
- 网络流之最大流sap算法
- 《算法导论》观后感想1
- dataguard的保护模式转化和主从切换
- sl6.1的PACCT日志位置
- Linux下grep命令详解
- struts2的maven配置
- Command line (cmd, powershell etc)
- iphone emoji
- hdu 2071