最小费spfa()+ek() 邻接表
2015-09-05 10:18
351 查看
/** 贴下最小费的邻接表模板 图算法中邻接表应用极其广泛,在速度和边处理方面都要比矩阵好很多 最小费邻接矩阵模板前面提到了 就不多说了 包括添边等常用的技巧前面也都提到了 就是求网络流是会用到逆流边 用邻接表添边,逆流边也相当经典,这个技巧刚开始并不好理解 比如:设edge[p] = ab; 则逆流边为 edge[p^1] = ba; p^1 这是个什么东西?? ^ 这个符号是异或,p^1 = ??? 如果p 为偶数则 p^1 = p+1, 如果p 为奇数 p^1 = p-1; 所以p^1 总能得到一个与自己相邻的数 把这个现象用到解决逆流边上面,因为添边时候的下一条边就为逆流边 所以如果从一个偶数开始 比如:从2开始 edge[2] = ab; edge[3] = ba; edge[4] = bc; edge[5] = cb; 每次都会添两条边,所以下一条边开始必为偶数 p ,而它的逆流边即为 p^1 具体看代码 */ struct { int v, cap, cost, next; }edge[eM]; //边结构体 eM为 最多有多少条边 int ne, edgeHead[nM]; //nM为 点的个数 int pre[nM]; //用来记录增广路径 int ans, ne; void addEdge(int u, int v, int c, int w) { edge[ne].v = v; edge[ne].cap = c; edge[ne].cost = w; edge[ne].next = edgeHead[u]; edgeHead[u] = ne++; edge[ne].v = u; edge[ne].cap = 0; edge[ne].cost = -w; edge[ne].next = edgeHead[v]; edgeHead[v] = ne++; } bool spfa(int s, int t) { //spfa算法前面也介绍过,这里用的栈模式,还有一个队列版,简单修改下就能得到 //一定要记住有时栈会超时,有时队列也会超时,总有一个能过 int dis[nM], stack[nM], vis[nM]; int i, top = 0; for (i=0; i<=n; i++) { dis[i] = inf; vis[i] = false; } dis[s] = 0; stack[++top] = s; vis[s] = true; while (top) { int u = stack[top--]; for (i=edgeHead[u]; i!=0; i=edge[i].next) { int v = edge[i].v; if (edge[i].cap && dis[v] > dis[u] + edge[i].cost) { dis[v] = dis[u] + edge[i].cost; pre[v] = i; //记录路径用的是边号,所以 u = edge[p^1].v; if (!vis[v]) { vis[v] = true; stack[++top] = v; } } } vis[u] = false; } if (dis[t] < inf) return true; return false; } void end(int s, int t) { //这些原理和邻接矩阵一模一样 int u, p, sum = inf; for (u=t; u!=s; u=edge[p^1].v) { p = pre[u]; sum = min(sum, edge[p].cap); } for (u=t; u!=s; u=edge[p^1].v) { //嗯,这个好好模拟下,技巧噢 p = pre[u]; edge[p].cap -= sum; edge[p^1].cap += sum; ans += edge[p].cost * sum; } } int main() { //初始化 memset(edgeHead, 0, sizeof (edgeHead)); ne = 2; //一定要从偶数开始,因为edgeHead 初始化为0 了所以赋值为2 ans = 0; //最小费 /** ***建图添边**** 调用addEdge()添边,uv 表示一条边,c为流量,w为花费 则 addEdge(u, v, c, w); 即可 这才是重重之中的技能 关键在建图,模板都会套 */ //调用 while (spfa(s, t)) end(s, t); //s为源点,t为汇点 return 0; } 收藏于 2012-01-12
相关文章推荐
- Apache Camel的routingSlip简单示例
- 学习C++的50条忠告
- [转]Android Parcelable和Serializable的区别
- poj 1182 食物链(并查集)
- Android笔记:Fragment与ViewPager组合时,如何在FragmentActicity获取Fragment对象
- .NET基础 (03)生成、部署和管理
- 拓扑排序 topsort()
- LeetCode #4 (A nice explanation from MissMary)
- css3新特性
- 黑马程序员--OC继承
- 僵尸网络的工作原理与防御
- 11.8 Matlab 学习相关的函数功能
- hdu 5237__Base64
- 小知识+碎东西
- STL hash_map 底层初探
- 在HTTP请求的header头里面,为什么有的时候有X-Powered-By这个值,有的时候没有呢?
- ubuntu12.04 install wine-qqintl.zip
- hdu(5326)——Work
- js实现图片放大和拖拽特效代码分享
- Spring MVC 两种方式