最大流—— SAP算法
Posted wuliking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大流—— SAP算法相关的知识,希望对你有一定的参考价值。
直接上代码
#include<vector> #include<cstdio> #include<iostream> #include<cmath> #include<queue> #define numm ch-48 #define pd putchar(‘ ‘) #define pn putchar(‘\n‘) #define pb push_back #define fi first #define se second #define fre1 freopen("1.txt","r",stdin) #define fre2 freopen("2.txt","w",stdout) using namespace std; template <typename T> void read(T &res) bool flag=false;char ch; while(!isdigit(ch=getchar())) (ch==‘-‘)&&(flag=true); for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); flag&&(res=-res); template <typename T> void write(T x) if(x<0) putchar(‘-‘),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); const int maxm=8000010; ///有反向边,边数要开两倍 const int maxn=1000010; const int inf=0x3f3f3f3f; const int INF=0x7fffffff; typedef long long ll; struct node ///链式前向星 ll c; int to,net; e[maxm]; int head[maxn],cur[maxn],numh[maxn],h[maxn],pre[maxn]; ///head:链式前向星头结点数组 ///cur:当前弧数组 ///numh:GAP优化的统计高度数量数组 ///h:距离标号数组 ///pre:前驱数组 int n,cnt=0; void init() // cnt=0; // for(int i=1;i<=n;i++) ///单测试用例可不用 // h[i]=0,numh[i]=0; for(int i=1;i<=n;i++) head[i]=-1,pre[i]=-1; void add(int u,int v,ll c) e[cnt].to=v; e[cnt].c=c; e[cnt].net=head[u]; head[u]=cnt++; ll SAP_Max_Flow(int st,int ed) ll max_flows=0; ///最大流 int i,u=st; numh[0]=n; for(int i=1;i<=n;i++) cur[i]=head[i]; while(h[st]<n) ///h[st]>=N时,网络中肯定出现了GAP(分层) if(u==ed) int neck; ///瓶颈 ll minn=INF; for(i=st;i!=ed;i=e[cur[i]].to) if(minn>e[cur[i]].c) minn=e[cur[i]].c; neck=i; for(i=st;i!=ed;i=e[cur[i]].to) int tmp=cur[i]; e[tmp].c-=minn; e[tmp^1].c+=minn; max_flows+=minn; u=neck; for(i=cur[u];i!=-1;i=e[i].net) if(e[i].c&&h[u]==h[e[i].to]+1) break; ///寻找可行弧 if(i!=-1) cur[u]=i; pre[e[i].to]=u; u=e[i].to; else if(--numh[h[u]]==0) break; cur[u]=head[u]; int tmp; for(tmp=n,i=head[u];i!=-1;i=e[i].net) if(e[i].c) tmp=min(tmp,h[e[i].to]); h[u]=tmp+1; numh[h[u]]++; if(u!=st) u=pre[u]; ///重标号并从当前点前驱重新增广 return max_flows; int main() int st,m,ed; read(n),read(m),read(st),read(ed); init(); for(int i=1;i<=m;i++) int u,v; ll c; read(u),read(v),read(c); add(u,v,c); add(v,u,0); ///建立反向边 write(SAP_Max_Flow(st,ed)); return 0; ///SAP算法:GAP优化+当前弧优化
以上是关于最大流—— SAP算法的主要内容,如果未能解决你的问题,请参考以下文章
hiho一下 第115周:网络流一?Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)