关于有容量下界的网络可行流问题解决的学习笔记 ZOJ 2314 ZOJ 3229 HDU 3157
2013-08-06 20:15
441 查看
白书二代上提到了无源无汇有容量下界网络可行流和有容量下界网络的s-t最大/最小流问题。
但是由于本人智商捉鸡,觉得LRJ大神写的似乎不是很好理解,所以只能找一些题目来帮助自己理解理解了。
这里直说方法,证明。。。不会。
1.无源无汇有容量下界可行流
这个问题的解法在周源的那个论文里讲的很清楚了。
对于每条边,都有一个容量下界b和一个容量上界c,那么这条边实际的可行流量只有c-b,剩下的b必须满流。
对每个点i,求a = sum(流向它的下界流)-sum(从它流出的下界流量)
若a>0,从源点0连一条到i的容量为a的边
若a<0,从i连一条到汇点n+1的容量为-a的边
(我觉得其实这里都是为求自由流做的准备)
然后求一次最大流,若所有从源点出发的点都满流,则有可行流,每条边的可行流为求最大流后的实际流量flow+该边的流量下界b
题目:ZOJ 2314
代码:
View Code
但是由于本人智商捉鸡,觉得LRJ大神写的似乎不是很好理解,所以只能找一些题目来帮助自己理解理解了。
这里直说方法,证明。。。不会。
1.无源无汇有容量下界可行流
这个问题的解法在周源的那个论文里讲的很清楚了。
对于每条边,都有一个容量下界b和一个容量上界c,那么这条边实际的可行流量只有c-b,剩下的b必须满流。
对每个点i,求a = sum(流向它的下界流)-sum(从它流出的下界流量)
若a>0,从源点0连一条到i的容量为a的边
若a<0,从i连一条到汇点n+1的容量为-a的边
(我觉得其实这里都是为求自由流做的准备)
然后求一次最大流,若所有从源点出发的点都满流,则有可行流,每条边的可行流为求最大流后的实际流量flow+该边的流量下界b
题目:ZOJ 2314
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #define maxn 60 #define INF 1000000000 using namespace std; struct Edge{ int from,to,cap,flow; }; struct Dinic{ int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void ClearAll(int n){ for(int i = 0;i < n;i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap){ edges.push_back((Edge){from,to,cap,0}); edges.push_back((Edge){to,from,0,0}); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS(){ memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(s); vis[s] = 1; d[s] = 0; while(!Q.empty()){ int x = Q.front();Q.pop(); for(int i = 0;i < G[x].size();i++){ Edge& e = edges[G[x][i]]; if(!vis[e.to] && e.cap > e.flow){ vis[e.to] = 1; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a){ if(x == t || a == 0) return a; int flow = 0,f; for(int& i = cur[x];i < G[x].size();i++){ Edge& e = edges[G[x][i]]; if(d[x] + 1 == d[e.to] && (f = DFS(e.to,min(a,e.cap-e.flow))) > 0){ e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow; } int Maxflow(int s,int t){ this->s = s;this->t = t; int flow = 0; while(BFS()){ memset(cur,0,sizeof(cur)); flow += DFS(s,INF); } return flow; } }; Dinic g; int in[maxn]; int main() { int n,m,s,t,SS,TT,a,b,cir; char from[10],to[10]; while(scanf("%d%d",&n,&m),n+m){ memset(in,0,sizeof(in)); g.ClearAll(n+5); s = 0,t = n+1,SS = t+1,TT = SS+1; int sum = 0; for(int i = 0;i < m;i++){ scanf("%s%s%d",from,to,&cir); if(from[0] == '+') a = s; else sscanf(from,"%d",&a); if(to[0] == '-') b = t; else sscanf(to,"%d",&b); in[a] -= cir;in[b] += cir; g.AddEdge(a,b,INF-cir); } for(int i = 0;i <= t;i++){ if(in[i] > 0) g.AddEdge(SS,i,in[i]),sum += in[i]; if(in[i] < 0) g.AddEdge(i,TT,-in[i]); } int flow1 = g.Maxflow(SS,TT); g.AddEdge(t,s,INF); int flow2 = g.Maxflow(SS,TT); if(flow1 + flow2 != sum) printf("impossible\n"); else{ int e = g.edges.size() - 2; printf("%d\n",g.edges[e].flow); } } return 0; }
View Code
相关文章推荐
- Xcode学习笔记中关于如何定义宏问题解决
- Xcode学习笔记中关于如何定义宏问题解决
- 菜鸟学习嵌入式 问题笔记之 关于-/bin/sh: 命令:not found的解决办法
- zoj 3229 上下界网络最大可行流带输出方案
- 【树莓派学习笔记】关于树莓派2代,更新最新内核后,DS18B20温度传感器无法找到对应文件的问题的解决
- 菜鸟学习嵌入式 问题笔记之 关于-/bin/sh: 命令:not found的解决办法
- robot framework学习笔记之八—解决列表或者字典中文乱码问题
- cocos2d-x-3.1 国际化strings.xml解决乱码问题 (coco2d-x 学习笔记四)
- ObjectArx学习笔记-Object 2013 Wizard问题解决
- vue饿了么学习笔记(1)关于dev-server.js消失的问题
- 【IOS学习之路】关于GPRS下上传文件,ASIFormDataRequest在2G网络下上传失败(已解决)iphone开发
- IOS学习笔记36—解决键盘遮挡输入框(UITextField)问题
- [openCV学习笔记]——关于waitKey(0)不起作用的问题
- 学习笔记20170312——JAVA解决农场母牛生baby的问题
- 安卓学习笔记---解决Android签名混淆后WebView与JS交互失效的问题
- 【Cocos2d-X开发学习笔记】解决Cocos2d-X新建项目运行报错的问题
- 深度学习笔记:交叉熵(cross-entropy)损失函数解决二次型带来的学习速率下降问题
- iOS学习笔记24—URL传参的问题和解决方法
- Spring学习笔记(二十三):关于STS提示"javax.servlet.http.HttpServletRequest cant be resolved"的问题
- html学习笔记-解决ie6中png图片透明不能正常显示问题