网络流之最大流-我的模板
来源:互联网 发布:iphone6s密码解锁软件 编辑:程序博客网 时间:2024/06/04 18:04
以HDU 3549这道模板题来分别给出我的EK,DINIC,SAP算法,原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=3549
一般地,求解最大流问题存在EK,DINIC,SAP三种算法。EK算法是基于BFS寻找增广路的,SAP算法是利用距离标号,DINIC算法是利用分层网络来寻找增广路。具体原理和一些基本概念我这里就不再赘述了。相关书籍已经写得非常清楚了。我是参考《ACM-ICPC程序设计系列-图论及其应用》的第5章的网络流。
下面给出我的三种算法的模板,都通过了HDU3549的测试。
EK算法
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<sstream>#include<vector>#include<map>#include<stack>#include<list>#include<set>#include<queue>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1using namespace std;const int maxn=55,maxe=10005,inf=1<<29;int n,m;int Map[maxn][maxn],p[maxn];bool EK_BFS(int s,int e){ queue<int>q; bool vis[maxn]; memset(vis,0,sizeof(vis)); memset(p,-1,sizeof(p)); q.push(s); vis[s]=1; while(!q.empty()) { int t=q.front();q.pop(); if(t==e) return 1; for(int i=1;i<=n;i++) if(Map[t][i]&&!vis[i]) vis[i]=1,p[i]=t,q.push(i); } return 0;}int EK_Max_Flow(int s,int e){ int ans=0,u,temp; while(EK_BFS(s,e)) { temp=inf; u=e; while(p[u]!=-1) temp=min(temp,Map[p[u]][u]),u=p[u]; ans+=temp; u=e; while(p[u]!=-1) Map[p[u]][u]-=temp,Map[u][p[u]]+=temp,u=p[u]; } return ans;}int main(){ int t; scanf("%d",&t); for(int T=1;T<=t;T++) { memset(Map,0,sizeof(Map)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); Map[x][y]+=c; } printf("Case %d: %d\n",T,EK_Max_Flow(1,n)); } return 0;}----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SAP算法
<pre name="code" class="cpp">#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<sstream>#include<vector>#include<map>#include<stack>#include<list>#include<set>#include<queue>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1using namespace std;const int maxn=1005,maxe=10005,inf=1<<29;int n,m;struct edge{ int to,cap,rev;};vector<edge>G[maxn];int level[maxn],iter[maxn];bool vis[maxn];void add(int from,int to,int cap){ G[from].push_back((edge){to,cap,G[to].size()}); G[to].push_back((edge){from,0,G[from].size()-1});}void bfs(int s){ memset(level,-1,sizeof(level)); queue<int>q; level[s]=0; q.push(s); while(!q.empty()) { int v=q.front();q.pop(); for(int i=0;i<G[v].size();i++) { edge &e=G[v][i]; if(e.cap>0&&level[e.to]<0) { level[e.to]=level[v]+1; q.push(e.to); } } }}int dfs(int v,int t,int f){ if(v==t) return f; for(int &i=iter[v];i<G[v].size();i++) { edge &e=G[v][i]; if(e.cap>0&&level[v]<level[e.to]) { int d=dfs(e.to,t,min(f,e.cap)); if(d>0) { e.cap-=d; G[e.to][e.rev].cap+=d; return d; } } } return 0;}int max_flow(int s,int t){ int flow=0; while(true) { bfs(s); if(level[t]<0) return flow; memset(iter,0,sizeof(iter)); int f; while((f=dfs(s,t,inf))>0) flow+=f; }}int main(){ int t; scanf("%d",&t); for(int T=1;T<=t;T++) { for(int i=0;i<=n;i++) G[i].clear(); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); add(x,y,c); } printf("Case %d: %d\n",T,max_flow(1,n)); } return 0;}
----------------------------------------------------------------------------------------------------------------------------------DINIC算法
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<sstream>#include<vector>#include<map>#include<stack>#include<list>#include<set>#include<queue>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1using namespace std;const int maxn=1005,maxe=100005,inf=1<<29;int n,m;int level[maxn];struct node{ int to,next,f;}edge[maxe];int head[maxn],cnt;void add(int from,int to,int f1,int f2){ edge[cnt].to=to; edge[cnt].f=f1; edge[cnt].next=head[from]; head[from]=cnt++; edge[cnt].to=from; edge[cnt].f=f2; edge[cnt].next=head[to]; head[to]=cnt++;}bool makelevel(int s,int t){ memset(level,0,sizeof(level)); level[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int top=q.front();q.pop(); if(top==t) return 1; for(int i=head[top];i!=-1;i=edge[i].next) if(!level[edge[i].to]&&edge[i].f) q.push(edge[i].to),level[edge[i].to]=level[top]+1; } return 0;}int dfs(int now,int Maxf,int t){ int ans=0; if(now==t) return Maxf; for(int i=head[now];i!=-1;i=edge[i].next) if(edge[i].f&&level[edge[i].to]==level[now]+1) { int f=dfs(edge[i].to,min(Maxf-ans,edge[i].f),t); edge[i].f-=f; edge[i^1].f+=f; ans+=f; if(ans==Maxf) return ans; } return ans;}int dinic(int s,int t){ int ans=0; while(makelevel(s,t)) ans+=dfs(s,inf,t); return ans;}int main(){int t; scanf("%d",&t); for(int T=1;T<=t;T++) { cnt=0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); add(x,y,c,0); } printf("Case %d: %d\n",T,dinic(1,n)); } return 0;}
0 0
- 网络流之最大流-我的模板
- 网络流之最大流模板
- 网络最大流之dinic模板
- 最大网络流 模板
- 【模板】网络最大流
- poj 网络最大流模板
- [模板练习]网络最大流
- P3376 【模板】网络最大流
- 网络流最大流之Dinic算法模板
- 【网络流之最大流】POJ1273-Drainage Ditche【模板题】
- 网络流之最大流算法模板EK
- 【网络流之最大流】HDU3549Flow Problem【EK模板】
- 最大网络流spa模板 优化的额
- 网络流之模板
- 网络流最大流模板(poj1273)
- 网络流最大流EdmondKarp、SAP【模板】
- 网络流最大流sap算法模板
- 网络流(最大流+模板)
- Hibernate中execute、executeQuery和executeUpdate之间的区别
- 在线作图工具ProcessOn(流程图)
- Java获取用户真实IP
- 第16周项目2-(2)
- Transactional超时时间控制
- 网络流之最大流-我的模板
- oracle表与表之间连接对比整理
- linux--帮助命令整理
- Cesysgen Conditional Statements (Compact 2013)
- 我对自己的总结,也只有这样才能进步啦
- 解决easyui tabs中href无法跨域跳转
- MySQL存储引擎【InnoDB、MyISAM、Memory】
- hadoop运行wordcount的路径问题
- Nim游戏博弈(收集完全版)