SAP算法

SAP算法

网络流中性能与复杂度最适合的算法就是SAP算法了,且易于编写,由于该说的东西太多所以我就不说了各位自行翻书吧。

代码:


struct Edge{
 int u,v,cap,flow,next; //从u到v有一条容量为cap,流量为flow的边
} E[maxn];

void addadge(int x,int y,int cap) //加边
{
 E[++Esize]=(Edge){x,y,cap,0,last[x]},last[x]=Esize;
 E[++Esize]=(Edge){y,x,0,0,last[y]},last[y]=Esize;
}

int calc() //到达汇点,计算流量
{
 x=t,k=INF;
 while (x!=s) k=min(k,E[F[x]].cap-E[F[x]].flow),x=E[F[x]].u;
 
 x=t;
 while (x!=s) E[F[x]].flow+=k,E[F[x]^1].flow-=k,x=E[F[x]].u; //将正向边流量加上k,反向减去k。
 
 return k;
}

void BFS(int t)
{
 memset(vis,0,sizeof(vis));
 L=1,R=1,Q[1]=t,d[t]=0,vis[t]=1;
 
 while (L<=R)
 {
  x=Q[L],L++;
  for (int i=last[x];i;i=E[i].next)
  {
   v=E[i].v;
   if (!vis[v]) Q[++R]=v,d[v]=d[x]+1,vis[v]=1;
  }
 }
}

int Maxflow(int s,int t)
{
 flow=0,BFS(t); //广搜计算d数组
 
 memset(num,0,sizeof(num));
 rep(i,1,n) num[d[i]]++; //gap优化,当某一num值为0说明不存在增广路

 rep(i,1,n) cur[i]=last[i]; //当前弧优化
 x=s;

 while (d[s]<n)
 {
  if (x==t) flow+=calc(),x=s; //到达汇点,计算

  mark=0;
  for (int i=cur[x];i;i=E[i].next)
  {
   if ((E[i].cap>E[i].flow)&&(d[x]==(d[E[i].v]+1)))
   {
    mark=1;
    F[E[i].v]=i,cur[x]=i,x=E[i].v;
    break;
   }
  }

  if (!mark) //无路可走,返回
  {
   mini=n-1;
   for (int i=last[x];i;i=E[i].next) 
    if (E[i].cap>E[i].flow) mini=min(mini,d[E[i].v]);
   
   if ((--num[d[x]])==0) break; //num为0,无增广路
   d[x]=mini+1,num[d[x]]++; //计算新的d值

   cur[x]=last[x];
   if (x!=s) x=E[F[x]].u;
  }
 }
 return flow;
}
posted @ 2017-01-02 17:42  Krew  阅读(320)  评论(0)    收藏  举报