最大流ISAP+Dinic
来源:互联网 发布:java 字符串反转 编辑:程序博客网 时间:2024/05/17 01:01
快速最大流ISAP模板
//By kuangbin//只能求一次最大流#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>const int MAXN=20010;const int MAXM=440020;//注意边的数目,因为连边是连两条/经常reconst int INF=0x3f3f3f3f;using namespace std;//int n,s,t,N;//输入的顶点数,源点,汇点,总顶点数struct Edge { int to,next,cap,flow;} edge[MAXM<<1];int head[MAXN],tot,gap[MAXN],d[MAXN],cur[MAXN],que[MAXN],p[MAXN];void init(){ tot=0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int c){ edge[tot].to = v; edge[tot].cap = c; edge[tot].flow = 0; edge[tot].next = head[u]; head[u] = tot++; edge[tot].to = u; edge[tot].cap = 0; edge[tot].flow = 0; edge[tot].next = head[v]; head[v] = tot++;}void BFS(int source,int sink){ memset(d,-1,sizeof(d));//clr(d,-1); memset(gap,0,sizeof(gap));//clr(gap,0); gap[0] = 1; int front = 0,rear = 0; d[sink] = 0; que[rear++] = sink; while(front != rear) { int u = que[front++]; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(d[v] != -1) continue; que[rear++] = v; d[v] = d[u]+1; gap[d[v]]++; } }}int isap(int source,int sink,int N){ BFS(source,sink); memcpy(cur,head,sizeof(head)); int top = 0,x = source,flow = 0; while(d[source] < N) { if(x == sink) { int Min = INF,inser; for(int i = 0; i < top; ++i) { if(Min > edge[p[i]].cap - edge[p[i]].flow) { Min = edge[p[i]].cap - edge[p[i]].flow; inser = i; } } for(int i = 0; i < top; ++i) { edge[p[i]].flow += Min; edge[p[i]^1].flow -= Min; } flow += Min; top = inser; x = edge[p[top]^1].to; continue; } int ok = 0; for(int i = cur[x]; i != -1; i = edge[i].next) { int v = edge[i].to; if(edge[i].cap > edge[i].flow && d[v]+1 == d[x]) { ok = 1; cur[x] = i; p[top++] = i; x = edge[i].to; break; } } if(!ok) { int Min = N; for(int i = head[x]; i != -1; i = edge[i].next) { if(edge[i].cap > edge[i].flow && d[edge[i].to] < Min) { Min = d[edge[i].to]; cur[x] = i; } } if(--gap[d[x]] == 0) break; gap[d[x] = Min+1]++; if(x != source) x = edge[p[--top]^1].to; } } return flow;}
//这个模板有待商榷const int maxn= 405;//最大顶点数const int maxm = 160005;//最大边数const int INF=0x3f3f3f3f;using namespace std;int n,s,t,N;//输入的顶点数,源点,汇点,建图后的总顶点数(判断dis[s]<N)struct node{ int to,cap,next,pre;//pre是指互为反向弧}edges[maxm];int head[maxn],tot,que[maxn],d[maxn],gap[maxn],cur[maxn],rpath[maxn];//邻接表,边数,队列,距离标号,间隙优化,当前弧,可增广路上的弧编号void init(){ tot=0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int c){ edges[tot].to=v; edges[tot].cap=c; edges[tot].next=head[u]; head[u] = tot ++; edges[tot-1].pre=tot; edges[tot].pre = tot-1; edges[tot].cap = 0; edges[tot].to = u; edges[tot].next = head[v]; head[v] = tot ++;}void re_Bfs(){ memset(gap,0,sizeof(gap)); memset(d,-1,sizeof(d)); int i,front=0,rear=0; que[rear ++] = t; gap[0] = 1; d[t] = 0; while(front != rear){ int u = que[front ++]; for(i = head[u];i != -1;i = edges[i].next){ if(edges[edges[i].pre].cap == 0 || d[edges[i].to]!=-1) continue; d[edges[i].to] = d[u] + 1; gap[d[edges[i].to]] ++; que[rear ++] = edges[i].to; } }}int ISAP(){ re_Bfs(); memcpy(cur,head,sizeof(head)); int i,u=s,maxflow = 0; while(d[s] < N){ if(u == t){ int curflow = INF; for(i = s;i != t;i = edges[cur[i]].to) curflow = min(curflow,edges[cur[i]].cap); for(i = s;i != t;i = edges[cur[i]].to){ edges[cur[i]].cap -= curflow; edges[edges[cur[i]].pre].cap += curflow; } maxflow += curflow; u = s; } for(i = cur[u];i != -1;i = edges[i].next) if(edges[i].cap > 0 && d[edges[i].to] + 1 == d[u]) break; if(i != -1){ cur[u] = i; rpath[edges[i].to] = edges[i].pre; u = edges[i].to; } else{ if((-- gap[d[u]]) == 0) break; cur[u] = head[u]; int Min = N; for(i = cur[u];i != -1;i = edges[i].next) if(edges[i].cap > 0) Min = min(Min,d[edges[i].to]); gap[d[u]=Min+1] ++; if(u != s) u = edges[rpath[u]].to; } } return maxflow;}
Isap//速度好慢的
//注意给源点,汇点,结点总个数n 赋值,最大距离标号的修改#include<iostream>#include<cstring>#include<cstdio>#include<vector>const int maxn=210;//最大结点数const int INF=0x3f3f3f3f;using namespace std;int n,s,t,N;//输入的顶点数,源点,汇点,总顶点数struct Edge{ int from,to,cap,flow; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};vector<Edge> edges;//边集vector<int> G[maxn];//顶点集int gap[maxn],d[maxn],cur[maxn],p[maxn];//间隙优化,距离标号,当前弧,可增广路上的上一条弧inline void addedge(int u,int v,int c){ edges.push_back(Edge(u,v,c,0)); edges.push_back(Edge(v,u,0,0)); int m=edges.size(); G[u].push_back(m-2); G[v].push_back(m-1);}int ISAP(int S,int T){ s=S,t=T;//别忘了赋值和修改 memset(cur,0,sizeof(cur)); memset(d,0,sizeof(d)); memset(gap,0,sizeof(gap)); int x=s,flow=0,a=INF; while(d[s]<N){ if(x==t){ flow+=a; while(x!=s){ edges[p[x]].flow+=a; edges[p[x]^1].flow-=a; x=edges[p[x]].from; } a=INF; } 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[e.to]+1==d[x]){ p[e.to]=G[x][i]; cur[x]=i; x=e.to; ok=1; a=min(a,e.cap-e.flow); break; } } if(!ok){ int m=N;//为 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(--gap[d[x]]==0) break; gap[d[x]=m+1]++; cur[x]=0; if(x!=s) x=edges[p[x]].from; } } return flow;}
————————————————————————————
Dinic
#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<queue>const int maxn=1100;//最大顶点数const int maxm=1100;//最大边数const int INF=0x3f3f3f3f;//无穷大using namespace std;int n,m,s,t;//输入的顶点数,输入的边数,源点,汇点struct Edge{ int from,to,cap,flow;};vector<Edge> edges;//边集vector<int> G[maxn];//顶点集int d[maxn],cur[maxn];//距离标号,当前弧bool vis[maxn];//标记数组inline void addedge(int u,int v,int c){ edges.push_back((Edge){u,v,c,0}); edges.push_back((Edge){v,u,0,0}); int x=edges.size(); G[u].push_back(x-2); G[v].push_back(x-1);}bool BFS(){//构建层次网络 memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(s); d[s]=0; vis[s]=1; 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 Dinic(int S,int T){ s=S,t=T; int flow=0; while(BFS()){ memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); } return flow;}
0 0
- 最大流ISAP+Dinic
- 最大流模板(Dinic, ISAP)
- 最大流算法,Dinic,ISAP
- : 最大流(Dinic算法 + ISAP算法)
- 网络流模板:最大流ISAP算法和Dinic算法
- 网络流模板:最大流ISAP算法和Dinic算法
- POJ-3281 : 最大流(Dinic算法 + ISAP算法)
- 最大流Dinic算法讲解 && ISAP 算法解释
- POj 1273 Drainage Ditches (最大流 Dinic + ISAP 模板)
- 网络流模板 Dinic+ISAP
- 网络流(Dinic && ISAP)
- 网络流之最大流 EK/Dinic/Isap算法 学习笔记
- 网络流最大流算法(ISAP算法及DINIC算法)
- POJ--1273--Drainage Ditches【Dinic模板】【isap模板】网络最大流
- poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap
- poj_1459 Power Network(多源多汇最大网络流)(EK / dinic / ISAP)
- hdu 1532 Drainage Ditches(最大流 三种模板:EK、Dinic、isap)
- 最大流ISAP模板
- mysql主从基础知识
- 【JAVA编码专题】深入分析 Java 中的中文编码问题
- bzoj 1927 星际竞速(拆点费用流)
- linux目录
- C语言的发展历史
- 最大流ISAP+Dinic
- android webview 点击页面输入框导致页面变大问题的解决
- java的System.getProperty()方法可以获取的值
- c++vector用法
- 把Java数组转换为List时的注意事项
- C语言及程序设计提高例程-17 一维数组的定义和引用
- ssh 登录免密码设置
- C语言及程序设计提高例程-12 变量的存储类别
- C语言及程序设计提高例程-16 数组的引入