模板_网络流
来源:互联网 发布:免费换ip软件 编辑:程序博客网 时间:2024/04/30 05:52
首先来一个简单的EdmondsKarp算法,跟SPFA很像,BFS找最短路
#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<climits>#include<iostream>using namespace std;#define N 205struct Edge{ int fr,to,cap,flow; Edge(int u,int v,int c,int f):fr(u),to(v),cap(c),flow(f){}};struct EdmondsKarp{ int n,m; vector<Edge> edges; vector<int> G[N]; int a[N],p[N]; void init(int n){ for(int i=0;i<n;i++) G[i].clear(); edges.clear(); } void Add_Edge(int fr,int to,int cap){ edges.push_back(Edge(fr,to,cap,0)); edges.push_back(Edge(to,fr,0,0)); m=edges.size(); G[fr].push_back(m-2); G[to].push_back(m-1); } int Max_Flow(int s,int t){ int flow=0; for(;;){ memset(a,0,sizeof(a)); queue<int> Q; Q.push(s); a[s]=INT_MAX; 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(!a[e.to]&&e.cap>e.flow){ p[e.to]=G[x][i]; a[e.to]=min(a[x],e.cap-e.flow); Q.push(e.to); } } if(a[t]) break; } if(!a[t]) break; for(int u=t;u!=s;u=edges[p[u]].fr){ edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; } flow+=a[t]; } return flow; }}f;
唔……再来一个费用流吧
算法主体
int spfa(){ int s=hash(1,1)*2,t=hash(n,n)*2+1,x; queue<int> q;int b[N*N]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ d[hash(i,j)*2]=INF,b[hash(i,j)*2]=false; d[hash(i,j)*2+1]=INF,b[hash(i,j)*2+1]=false; } b[s]=true,d[s]=0,a[s]=1;q.push(s); while(!q.empty()){ x=q.front();q.pop();b[x]=false; for(int i=0;i<g[x].size();i++){ Edge& e=edge[g[x][i]]; if(e.cap>e.flow&&d[e.to]>d[x]+e.cost){ d[e.to]=d[x]+e.cost; p[e.to]=g[x][i]; a[e.to]=min(a[x],e.cap-e.flow); if(!b[e.to]) {b[e.to]=true;q.push(e.to);} } } } if(d[t]==INF) return 0; ans+=d[t]*a[t]; for(x=t;x!=s;x=edge[p[x]].fr){ edge[p[x]].flow+=a[t],edge[p[x]^1].flow-=a[t]; } return 1; }
最大流的高效算法Dinic算法,BFS建层次图,DFS找增广路,递归算法
bool bfs(){ memset(d,-1,sizeof(d));memset(b,0,sizeof(b)); queue<int> q;int x;d[S]=0;b[S]=true;q.push(S); while(!q.empty()){ x=q.front();q.pop(); for(int i=0;i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(!b[e.to]&&e.cap>e.flow){ b[e.to]=true;d[e.to]=d[x]+1;q.push(e.to); } } } return b[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=edge[g[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){ e.flow+=f;edge[g[x][i]^1].flow-=f; flow+=f;a-=f; if(a==0) break; } } return flow; } void Max_Flow(){ flow=0; while(bfs()){ memset(cur,0,sizeof(cur)); flow+=dfs(S,INF); } }
Dinic算法的非递归实现
bool bfs(){ memset(d,-1,sizeof(d));memset(b,0,sizeof(b)); queue<int> q;int x;d[S]=0;b[S]=true;q.push(S); while(!q.empty()){ x=q.front();q.pop(); for(int i=0;i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(!b[e.to]&&e.cap>e.flow){ b[e.to]=true;d[e.to]=d[x]+1;q.push(e.to); } } } return b[T]; } void Max_Flow(){ flow=0; while(bfs()){ int k=0,x=S; memset(cur,0,sizeof(cur)); for(;;){ if(x==T){ int mine=-1,minf=INF; for(int i=0;i<k;i++) if(edge[p[i]].cap-edge[p[i]].flow<minf){ minf=edge[p[i]].cap-edge[p[i]].flow; mine=i; } for(int i=0;i<k;i++){ edge[p[i]].flow+=minf; edge[p[i]^1].flow-=minf; } k=mine;x=edge[p[mine]].fr;flow+=minf; } for(int &i=cur[x];i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(e.cap>e.flow&&d[x]+1==d[e.to]) break; } if(cur[x]<g[x].size()){ p[k++]=g[x][cur[x]]; x=edge[g[x][cur[x]]].to; } else{ if(k==0) break; d[x]=-1;k--;x=edge[p[k]].fr; } } } }
最后比较神的算法,缩点全局最小割Stoer-Wagner
#include<cstdio>#include<climits>#include<cstring>#include<vector>#include<queue>#include<iostream>using namespace std;#define N 505#define INF INT_MAX/3*2struct Min_Cut{ struct Dist{ int s,d; /* Dist(int a,int b):s(a),d(b){} bool operator <(const Dist &b)const{ if(d==b.d) return s>b.s; return d<b.d; }*/ }; int mp[N][N];bool use[N]; int n,m,ans,S,T; int in(){ int x=0;char ch=getchar(); while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x; } void init(){ memset(mp,0,sizeof(mp));memset(use,0,sizeof(use)); int x,y,z;ans=INF; while(m--){ x=in(),y=in(),z=in(); mp[x][y]+=z;mp[y][x]+=z; } return; } int MinCut(int &s,int &t){ bool vis[N];int w[N]; memset(vis,0,sizeof(vis));memset(w,0,sizeof(w)); int tmpj=N; for(int i=0;i<n;i++){ int max=-INF; for(int j=0;j<n;j++){ if(!vis[j]&&!use[j]&&max<w[j]){ max=w[j]; tmpj=j; } } if(t==tmpj){return w[t];} vis[tmpj]=1; s=t,t=tmpj; for(int j=0;j<n;j++){ if(!vis[j]&&!use[j]) w[j]+=mp[t][j]; } } return w[t]; }/* int MinCut(int &S,int &T){ priority_queue<Dist> q;queue<Dist> p;Dist t(0,0); for(int i=0;i<n;i++) if(!use[i]) q.push(Dist(i,0)); while(!q.empty()){ t=q.top();q.pop(); if(T==t.s){return t.d;} S=T;T=t.s; while(!q.empty()){ p.push(q.top());q.pop(); } while(!p.empty()){ t=p.front();p.pop(); q.push(Dist(t.s,mp[T][t.s]+t.d)); } } return q.top().d; }*//* Dist heap[N*2];int size; void push(Dist x){ heap[++size]=x; int now,next;now=size,next=size/2; while(now>1){ next=now/2; if(heap[next].d>heap[now].d) break; else swap(heap[next],heap[now]); now=next; } return; } Dist top(){ Dist res=heap[1];heap[1]=heap[size--]; int now,next;now=1; while(now*2<=size){ next=now*2; if(next+1<=size&&heap[next].d>heap[next+1].d) next++; if(heap[now].d>heap[next].d) break; swap(heap[now],heap[next]); now=next; } return res; } int MinCut(int &S,int &T){ memset(heap,0,sizeof(heap));size=0; queue<Dist> p;Dist t; for(int i=0;i<n;i++) if(!use[i]){ t.s=i,t.d=0; push(t); } while(size){ t=top(); if(T==t.s){return t.d;} S=T;T=t.s; while(size) p.push(top()); while(!p.empty()){ t=p.front();p.pop();t.d+=mp[T][t.s]; push(t); } } return top().d; } */ void solve(){ while(scanf("%d%d",&n,&m)!=EOF){ init(); for(int i=1;i<n;i++){ S=T=-1;ans=min(ans,MinCut(S,T));use[T]=true; for(int j=0;j<n;j++){ mp[S][j]+=mp[T][j]; mp[j][S]+=mp[j][T]; } /*for(int o=0;o<n;o++){ for(int u=0;u<n;u++){ printf("%d ",mp[o][u]); } printf("\n"); }*/// printf("%d\n",ans); } printf("%d\n",ans); } return; }}s;int main(){ s.solve(); return 0;}
最后才搞得ISAP
#include<cstdio>#include<climits>#include<cstring>#include<queue>#include<vector>#include<iostream>using namespace std;#define N 505#define INF INT_MAX/3*2struct ISAP{ struct Edge{int fr,to,flow,cap;}; vector<Edge> edge;vector<int> g[N]; int p[N],num[N],cur[N];int s,t,n; bool v[N];int d[N]; void Add_Edge(int fr,int to,int flow,int cap){ edge.push_back(Edge{fr,to,flow,cap}); edge.push_back(Edge{to,fr,0,0}); g[fr].push_back(edge.size()-2);g[to].push_back(edge.size()-1); } int AddFlow(){ int x=t,a=INF;Edge e=edge[p[x]]; for(;x!=s;x=edge[p[x]].fr,e=edge[p[x]]) a=min(e.cap-e.flow,a); x=t; for(;x!=s;x=edge[p[x]].fr) edge[p[x]].flow+=a,edge[p[x]^1].flow-=a; return a; } void BFS(){ for(int i=0;i<n;i++) d[i]=n; memset(v,0,sizeof(v)); queue<int> q;int x;q.push(t);v[t]=true,d[t]=0; while(!q.empty()){ x=q.front();q.pop(); for(int i=0;i<g[x].size();i++){ Edge &e=edge[g[x][i]]; Edge &u=edge[g[x][i]^1]; if(!v[e.to]&&u.cap>u.flow){ d[e.to]=d[x]+1;v[e.to]=true; q.push(e.to); } } } } int MaxFlow(){ int flow=0,x=s;BFS(); memset(num,0,sizeof(num));memset(cur,0,sizeof(cur)); for(int i=0;i<n;i++) num[d[i]]++; while(d[s]<n){ if(x==t) flow+=AddFlow(),x=s; int ok=0; for(int i=cur[x];i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(e.cap>e.flow&&d[x]==d[e.to]+1){ ok=1;p[e.to]=g[x][i]; cur[x]=i;x=e.to;break; } } if(!ok){ int m=n-1; for(int i=0;i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(e.cap>e.flow) m=min(m,d[e.to]); } if(!(--num[d[x]])) break; num[d[x]=m+1]++;cur[x]=0; if(x!=s) x=edge[p[x]].fr; } } return flow; }}s;
1 0
- 模板_网络流
- ACM_模板_网络流
- 洛谷 3376_[模板]网络最大流
- 模板_poj1273Drainage Ditches_最大流问题_残留网络流增广解决(Ford-Fulkerson方法)
- 【网络流各种模板】
- 【模板】网络流
- 网络流模板--dinic
- 网络流模板--edmondsKarp
- 网络流模板--spfa
- 网络流(模板)
- 网络流算法模板
- 网络流模板
- 网络流模板
- 网络流基础模板
- 网络流SAP模板
- 网络流模板大全
- 最大网络流 模板
- 【网络流模板】
- 案例1判断闰年程序
- 关于UITableView的一些细小的知识点总结(持续更新)
- 大数据系列第六课:Spark集群环境搭建
- 【Bash百宝箱】Android源码下载及编译
- 使用Queryable.Join实现多表连接查询
- 模板_网络流
- hdu1042——N!
- 每天一个设计模式: 观察者模式(Observer)
- 演化计算会议
- 比大小 OJ 73
- 关于c语言char*的问题
- 20150108-小失误-中国流-执黑胜
- 案例2产生随机数并运算的程序
- 进程和线程的简单介绍