最大流模板
来源:互联网 发布:ubuntu安装openstack 编辑:程序博客网 时间:2024/05/22 09:40
Dinic算法-------来自LRJ
struct Edge{ int from, to, cap, flow;};struct Dinic{ int n, m ,s, t; vector<Edge> edges; VI G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn] ; void init(int nn) { this->n = nn; REP(i, n + 2) G[i].clear(); edges.clear(); } void addEdge(int from, int to, int cap) { edges.PB((Edge){from, to, cap, 0}); edges.PB((Edge){to, from, 0, 0}); m = edges.size(); G[from].PB(m - 2); G[to].PB(m - 1); } bool bfs() { CLR(vis, 0); queue<int> Q; Q.push(s); d[s] = 0; vis[s] = 1; while (!Q.empty()) { int x = Q.front(); Q.pop(); REP(i, G[x].size()) { 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; } //当所求流量大于need时就退出,降低时间 int maxflow(int s,int t,int need){ this->s = s; this->t = t; int flow = 0; while(bfs()) { CLR(cur ,0); flow += dfs(s,INF); if (flow > need) return flow; } return flow; } //最小割割边 vector<int> Mincut(){ 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 ClearFlow(){ for(int i = 0; i < edges.size(); i++) edges[i].flow = 0; }}sol;
ISAP最大流,效率高于Dinic
//ISAPstruct 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);}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); }};
- 最大流算法模板
- 最大流算法模板
- 最大流模板
- 最大流模板
- 最大流ISAP模板
- 最大流模板
- 最大流模板
- 最大流模板
- 最大流模板
- 最大流模板
- 最大流模板
- 最大流模板
- 最大流dinic模板
- 最大流Dinic模板
- 最大流 ISAP 模板
- 最大流dinci模板
- 最大网络流 模板
- 最大流模板
- poj 1637 混合图欧拉回路,最大流
- Linux NFS服务器的搭建
- HTML5 Local Storage( 本地存储) 的前世今生
- ubuntu 桥接方式 设置静态ip
- html网页自动跳转代码
- 最大流模板
- 一些查阅文档的网站
- ISBN 10位校验码的计算方法
- 创建ORACLE JOB
- java 对象序列化
- 使用ST05查找BADI
- 安装wxWidgets2.8
- Dojo入门:初识Dojo
- svn中库迁移和地址问题