[模版] 网络流最大流、费用流
2015-02-04 12:24
363 查看
反向边作用讨论:/article/1750135.html
我理解的很有限,希望有研究过的人能给我评论指导。
数据结构和比较函数(用于排序):
最大流:
1.Dinic
费用流:
zkw费用流(By:HZWER)
我理解的很有限,希望有研究过的人能给我评论指导。
代码:
By:Rujia Liu数据结构和比较函数(用于排序):
struct Edge { int from, to, cap, flow; }; bool operator < (const Edge& a, const Edge& b) { return a.from < b.from || (a.from == b.from && a.to < b.to); }
最大流:
1.Dinic
struct Dinic { int n, m, s, t; vector<Edge> edges; // 边数的两倍 vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[maxn]; // BFS使用 int d[maxn]; // 从起点到i的距离 int cur[maxn]; // 当前弧指针 void ClearAll(int n) { for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void ClearFlow() { for(int i = 0; i < edges.size(); i++) edges[i].flow = 0; } 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; } vector<int> Mincut() { // call this after maxflow vector<int> ans; for(int i = 0; i < edges.size(); i++) { Edge& e = edges[i]; if(vis[e.from] && !vis[e.to] && e.cap > 0) ans.push_back(i); } return ans; } void Reduce() { for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow; } };ISAP:
struct ISAP { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[maxn]; // BFS使用 int d[maxn]; // 从起点到i的距离 int cur[maxn]; // 当前弧指针 int p[maxn]; // 可增广路上的上一条弧 int num[maxn]; // 距离标号计数 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(t); vis[t] = 1; d[t] = 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]^1]; if(!vis[e.from] && e.cap > e.flow) { vis[e.from] = 1; d[e.from] = d[x] + 1; Q.push(e.from); } } } return vis[s]; } void ClearAll(int n) { this->n = n; for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void ClearFlow() { for(int i = 0; i < edges.size(); i++) edges[i].flow = 0; } int Augment() { int x = t, a = INF; while(x != s) { Edge& e = edges[p[x]]; a = min(a, e.cap-e.flow); x = edges[p[x]].from; } x = t; while(x != s) { edges[p[x]].flow += a; edges[p[x]^1].flow -= a; x = edges[p[x]].from; } return a; } int Maxflow(int s, int t, int need) { this->s = s; this->t = t; int flow = 0; BFS(); memset(num, 0, sizeof(num)); for(int i = 0; i < n; i++) num[d[i]]++; int x = s; memset(cur, 0, sizeof(cur)); while(d[s] < n) { if(x == t) { flow += Augment(); if(flow >= need) return flow; x = s; } int ok = 0; for(int i = cur[x]; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(e.cap > e.flow && d[x] == d[e.to] + 1) { // Advance ok = 1; p[e.to] = G[x][i]; cur[x] = i; // 注意 x = e.to; break; } } if(!ok) { // Retreat int m = n-1; // 初值注意 for(int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(e.cap > e.flow) m = min(m, d[e.to]); } if(--num[d[x]] == 0) break; num[d[x] = m+1]++; cur[x] = 0; // 注意 if(x != s) x = edges[p[x]].from; } } return flow; } vector<int> Mincut() { // call this after maxflow BFS(); vector<int> ans; for(int i = 0; i < edges.size(); i++) { Edge& e = edges[i]; if(!vis[e.from] && vis[e.to] && e.cap > 0) ans.push_back(i); } return ans; } void Reduce() { for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow; } void print() { printf("Graph:\n"); for(int i = 0; i < edges.size(); i++) printf("%d->%d, %d, %d\n", edges[i].from, edges[i].to , edges[i].cap, edges[i].flow); } };
费用流:
struct MCMF { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; int inq[maxn]; // 是否在队列中 int d[maxn]; // Beintman-Ford int p[maxn]; // 上一条弧 int a[maxn]; // 可改进量 void init(int n) { this->n = n; for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap, int cost) { edges.push_back((Edge){from, to, cap, 0, cost}); edges.push_back((Edge){to, from, 0, 0, -cost}); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BellmanFord(int s, int t, int& ans) { for(int i = 0; i < n; i++) d[i] = INF; memset(inq, 0, sizeof(inq)); d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF; queue<int> Q; Q.push(s); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if(e.cap > e.flow && d[e.to] > d[u] + e.cost) { d[e.to] = d[u] + e.cost; p[e.to] = G[u][i]; a[e.to] = min(a[u], e.cap - e.flow); if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; } } } } if(d[t] > 0) return false; ans += (int)d[t] * (int)a[t]; int u = t; while(u != s) { edges[p[u]].flow += a[t]; edges[p[u]^1].flow -= a[t]; u = edges[p[u]].from; } return true; } // 需要保证初始网络中没有负权圈 int Mincost(int s, int t) { int cost = 0; while(BellmanFord(s, t, cost)); return cost; } };
zkw费用流(By:HZWER)
bool spfa() { memset(mark,0,sizeof(mark)); for(int i=0;i<=T;i++)d[i]=-1; int head=0,tail=1; q[0]=T;mark[T]=1;d[T]=0; while(head!=tail) { int now=q[head];head++;if(head==605)head=0; for(int i=last[now];i;i=e[i].next) if(e[i^1].v&&d[now]+e[i^1].c>d[e[i].to]) { d[e[i].to]=d[now]+e[i^1].c; if(!mark[e[i].to]) { mark[e[i].to]=1; q[tail++]=e[i].to; if(tail==605)tail=0; } } mark[now]=0; } return d[0]!=-1; } int dfs(int x,int f) { mark[x]=1; if(x==T)return f; int w,used=0; for(int i=last[x];i;i=e[i].next) if(d[e[i].to]==d[x]-e[i].c&&e[i].v&&!mark[e[i].to]) { w=f-used; w=dfs(e[i].to,min(w,e[i].v)); ans+=w*e[i].c; e[i].v-=w;e[i^1].v+=w; used+=w;if(used==f)return f; } return used; } void zkw() { while(spfa()) { mark[T]=1; while(mark[T]) { memset(mark,0,sizeof(mark)); dfs(0,inf); } } }
相关文章推荐
- [模版] 网络流最大流、费用流
- 732. [网络流24题] 试题库 费用流/最大最小值
- POJ3469_Dual Core CPU(网络流/最小割=最大流/模版)----Dinic模版2.0
- 【网络流24题】数字梯形(二分图+最大费用流)
- 【bzoj3130】[Sdoi2013]费用流 二分+网络流最大流
- 网络流之最小费用最大流
- luogu4015: 运输问题(网络流/最小费用最大流/最大费用最大流)
- 【网络流24题】最长k可重区间集(最大费用流+二分图)
- 740. [网络流24题] 分配问题 费用流/求最大最小费用
- 网络流(最大费用最大流) :POJ 3680 Intervals
- nefu494深海机器人问题【网络流24题】最大费用流
- 最大费用最大流模版(POJ 3422)
- 线性规划与网络流24题之最长k可重区间集问题 最大权不相交路径(最大费用最大流)
- 【网络流24题】No.21 (最长 k 可重区间集问题 最长不相交路径 最大费用流)
- 【网络流24题】航空路线问题(最大费用流)
- 网络流入门 最大流,带下界,最小费用,EK算法,Dinic算法 模板
- 【网络流24题】分配问题 最小最大费用最大流
- 网络流&费用流模版
- 线性规划与网络流24题の17 运输问题(最小费用最大流、最大费用最大流)
- Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)