网络流最大流sap算法模板
来源:互联网 发布:c语言基础教程电子书 编辑:程序博客网 时间:2024/05/15 02:11
#include<cstdio>#include<cstring>using namespace std;const int M=500000,N=60000;const int INF = 0x3fffffff;struct Edge{ int from,to,cap,next;};int n,m;//总的点数,包括源点和汇点Edge edge[M];int q[N];int head[N],dep[N];//dep为距离编号int gap[N];//gap[x]=y:说明残留网络中dep[i]==x的节点有y个int cnt;void addedge(int u,int v,int w){ edge[cnt].from=u;edge[cnt].to=v;edge[cnt].cap=w;edge[cnt].next=head[u];head[u]=cnt++; edge[cnt].from=v;edge[cnt].to=u;edge[cnt].cap=0;edge[cnt].next=head[v];head[v]=cnt++;}struct SAP{ int sum; int src,des; void init(){ src = 0; des = n+m+1; cnt=0;sum=0; memset(head,-1,sizeof(head)); } void bfs(int start,int end){ memset(dep, -1, sizeof(dep)); memset(gap, 0, sizeof(gap)); memset(q,-1,sizeof(q)); gap[0]=1; int front,rear; front=rear=0; dep[end]=0; q[rear++]=end; while(front!=rear){ int u=q[front++]; if(front==N)front=0; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(dep[v]!=-1)continue; q[rear++]=v; if(rear==N)rear=0; dep[v]=dep[u]+1; ++gap[dep[v]]; } } } int Maxflow(){ int res=0; bfs(src,des); int cur[N],stack[N]; int top=0; memcpy(cur,head,sizeof(head)); int u=src; int i; while(dep[src]<n){//如果src找不到一个可达点,则dep[src] = n + 1自动退出 if(u==des){//找到汇点 int temp=INF,inser=n; for(int i=0;i<top;i++){//找从src点到des点的所有边中的最容量为temp,而那条边的编号为insert if(temp>edge[stack[i]].cap){ temp=edge[stack[i]].cap; inser=i; } } for(int i=0;i<top;i++){//将正向边-temp,反向变+temp edge[stack[i]].cap-=temp; edge[stack[i]^1].cap+=temp; } res+=temp;//总的流量加temp top=inser;//stack只保留从src到最小边insert“前向点”之间的边的信息,即insert边以后的边信息都不要 u=edge[stack[top]].from;////u为insert的”前向点“ } for(i=cur[u];i!=-1;i=edge[i].next){////当没有断层,找出一个可达边 if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)break; } if(i!=-1)//找到这个可达边,只能走到dep[u]-1; { cur[u]=i;//优化下次找dep[u] - 1不用从头开始找了 stack[top++]=i; u=edge[i].to; } else{//当没有找到深度为dep[u] - 1的可达边,那只能找深度更大的边 if(--gap[dep[u]]==0)break; //出现断层,无增广路; int minn = n; //从头开始找出深度最小的可达边 for(i=head[u];i!=-1;i=edge[i].next){ if(edge[i].cap==0)continue; if(minn>dep[edge[i].to]){ minn=dep[edge[i].to]; cur[u]=i; } } dep[u]=minn+1;//更新深度 ++gap[dep[u]]; if(u!=src)//如果u不是源点,还得回溯到dep[u] + 1(这里的dep[u]!=minn + 1)层,并将dep[u]层点全部修改变大。一直回溯到源点 u=edge[stack[--top]].from; } } return sum-res; }};SAP sap;int main(){ while(scanf("%d%d",&n,&m)!=EOF){ int w; sap.init(); //... printf("%d\n",sap.Maxflow()); } return 0;}
0 0
- 网络流最大流sap算法模板
- 网络最大流SAP算法
- 网络流最大流EdmondKarp、SAP【模板】
- 网络最大流(SAP)【模板】
- 网络最大流(SAP)模板
- 最大流 SAP模板
- 最大流Sap模板
- 最大流SAP模板
- SAP最大流模板
- 网络流之最大流sap算法
- 网络流最大流的sap()算法
- [转载]网络最大流SAP算法心得
- 网络流sap算法模板及分析
- 网络流SAP模板
- {模板}网络流SAP
- 最大流SAP算法
- 最大流SAP算法
- 最大流SAP算法
- WindowFromPoint -- 获得包含指定点的窗口的句柄
- VS2008中关于“加载安装组件时遇到问题。取消安装”的解决
- 《数学之美(第二版)》(五)
- 【Objective-C】内存管理
- 1.Android系统架构
- 网络流最大流sap算法模板
- 【Cocos2d-x 3.0学习笔记】 AnchorPoint 和Position 关系
- Android之——常见Bug及其解决方案
- VBS 函数和过程默认的传递方式
- HTML5使用Canvas完成刮刮乐效果
- Big Number(1018)
- NYOJ
- Spring和MyBatis环境整合
- sed命令总结