sap(邻接表)模板

<textarea cols="89" rows="15" name="code" class="cpp">const int null = -1; const int VMAX = 500; const int EMAX = 300000; struct Edge { int adj,next,re; //指向的点,下一边的下标,逆边的下标 int r; //余留网边的容量 }h[EMAX+10]; //用下标模拟指针构邻接表 int p[VMAX+10],c; int n,m,s,t; int gap[VMAX+10],pre[VMAX+10],dis[VMAX+10]; //插边,k,l为端点,cap为边容量 void insert(int k,int l,int cap) { h[++c].adj=l; h[c].r=cap; h[c].next=p[k]; p[k]=c; h[c].re=c+1; //逆边 h[++c].adj=k; h[c].r=0; h[c].next=p[l]; p[l]=c; h[c].re=c-1; //与上面对应 } int sap(int N) //N为点数(包括源汇) { memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); gap[0]=N; int u=s,ca=inf,ans=0; while (dis[s]&lt;N) { while (1) { bool flag=false; for (int j=p[u];j!=null;j=h[j].next) { int i=h[j].adj; if (h[j].r &amp;&amp; dis[u]==dis[i]+1) { ca=min(ca,h[j].r); pre[i]=j;u=i; //注意邻接表版的pre表示的是边 if (i==t) { ans+=ca; while (i!=s) { u=pre[i]; h[u].r-=ca; h[h[u].re].r+=ca; i=h[h[u].re].adj; } u=s;ca=inf; } flag=true; break; } } if (!flag) break; } int Min=N; for (int j=p[u];j!=null;j=h[j].next) if (h[j].r &amp;&amp; dis[h[j].adj]&lt;Min) Min=dis[h[j].adj]; if (--gap[dis[u]] == 0) break; gap[dis[u]=Min+1]++; if (u!=s) u=h[h[pre[u]].re].adj; } return ans; } void init() { c=-1; memset(p,-1,sizeof(p)); }</textarea>

你可能感兴趣的:(sap(邻接表)模板)