最大流最小割模板
Posted romalzhih
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大流最小割模板相关的知识,希望对你有一定的参考价值。
纯最大流,Dicnic算法:
1 using namespace std; 2 const int maxn=650; 3 const int INF=0x3f3f3f3f; 4 struct Edge{ 5 int from,to,cap,flow; 6 }; 7 struct Dinic{ 8 int n,m,s,t; 9 vector<Edge>edges; 10 vector<int>G[maxn]; 11 bool vis[maxn]; 12 int d[maxn]; 13 int cur[maxn]; 14 void AddEdge(int from,int to,int cap){ 15 edges.push_back((Edge){from,to,cap,0}); 16 edges.push_back((Edge){to,from,0,0}); 17 m=edges.size(); 18 G[from].push_back(m-2); 19 G[to].push_back(m-1); 20 } 21 bool BFS(){ 22 int x,i; 23 memset(vis,0,sizeof(vis)); 24 queue<int>Q; 25 Q.push(s); 26 d[s]=0; 27 vis[s]=1; 28 while(!Q.empty()){ 29 x=Q.front(),Q.pop(); 30 for(i=0;i<G[x].size();i++){ 31 Edge & e =edges[G[x][i]]; 32 if(!vis[e.to]&&e.cap>e.flow){ 33 vis[e.to]=1; 34 d[e.to]=d[x]+1; 35 Q.push(e.to); 36 } 37 } 38 } 39 return vis[t]; 40 } 41 int DFS(int x,int a){ 42 if(x==t||a==0) 43 return a; 44 int flow=0,f; 45 for(int &i=cur[x];i<G[x].size();i++){ 46 Edge & e=edges[G[x][i]]; 47 if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ 48 e.flow+=f; 49 edges[G[x][i]^1].flow-=f; 50 flow+=f; 51 a-=f; 52 if(a==0) 53 break; 54 } 55 } 56 return flow; 57 } 58 int Maxflow(int s,int t){ 59 this->s=s,this->t=t; 60 int flow=0; 61 while(BFS()){ 62 memset(cur,0,sizeof(cur)); 63 flow+= DFS(s,INF); 64 } 65 return flow; 66 } 67 };
Edmonds Karp模板
1 const int maxn=; 2 const int inf=0x3f3f3f3f; 3 struct Edge 4 { 5 int from,to,cap,flow; 6 Edge(int u,int v,int c,int f): from(u),to(v),cap(c),flow(f) {} 7 }; 8 9 struct EdmondsKarp 10 { 11 int n,m; 12 vector<Edge> edges; 13 vector<int> G[maxn]; 14 int a[maxn]; 15 int p[maxn]; 16 17 void init(int n) 18 { 19 for(int i=0;i<n;i++) G[i].clear(); 20 edges.clear(); 21 } 22 23 void AddEdge(int from,int to,int cap) 24 { 25 edges.push_back(Edge(from,to,cap,0)); 26 edges.push_back(Edge(to,from,0,0)); 27 m=edges.size(); 28 G[from].push_back(m-2); 29 G[to].push_back(m-1); 30 } 31 32 int Maxflow(int s,int t) 33 { 34 int flow=0; 35 while(1) 36 { 37 memset(a,0,sizeof(a)); 38 queue<int> Q; 39 Q.push(s); 40 a[s]=inf; 41 while(!Q.empty()) 42 { 43 int x=Q.front();Q.pop(); 44 for(int i=0;i<G[x].size();i++) 45 { 46 Edge& e=edges[G[x][i]]; 47 if(!a[e.to]&&e.cap>e.flow) 48 { 49 p[e.to]=G[x][i]; 50 a[e.to]=min(a[x],e.cap-e.flow); 51 Q.push(e.to); 52 } 53 } 54 if(a[t]) break; 55 } 56 if(!a[t]) break; 57 for(int u=t;u!=s;u=edges[p[u]].from) 58 { 59 edges[p[u]].flow+=a[t]; 60 edges[p[u]^1].flow-=a[t]; 61 } 62 flow+=a[t]; 63 } 64 return flow; 65 } 66 };
对于最小割来说,在算法结束后,令已经标号的结点(a[u]>0的结点)集合为S,其他集合为T=V-S,则(S,T)是图 s-t 的最小割
以上是关于最大流最小割模板的主要内容,如果未能解决你的问题,请参考以下文章