sap资料(取自nk)

             Shortest Augmenting Paths
                         最短增广路

              求最大流的高效算法

回忆Dinic:

数组dis[i]记录源点到点i的最短距离。g[i][j]记录边(i,j)的容量
算法过程如下: 1.初始化,将dis数组全部置为-1,dis[源]赋值为0 2.通过BFS计算每个点的dis,若算出dis[汇]=-1,则算法结束。 3.从源点出发,用DFS找增广路。       对于点x,若存在边(x,y),点y若要加入增广路就必须满足条件:       g[x][y]>0  并且 dis[x]+1=dis[y] 4.重复2,3,直到找不到增广路。

时间复杂度 O(v2e)!!!

SAP算法框架:

数组dis[i]记录点i到汇点的最短距离。g[i][j]记录边(i,j)的容量。
算法过程如下:

1.初始化,计算出每个点的dis

2.从源点出发,用DFS找增广路:       对于点x,若存在边(x,y),点y若要加入增广路就必须满足条件:       g[x][y]>0  并且 dis[x]-1=dis[y]        (边(x,y)称为允许边)       若对于点x,找不到满足上诉条件的y:dis[x]++

3.若走到汇点(找到增广路),修改增广路上每条边的容量,返回上一个点,继续搜索,......直到找不到增广路。


何时结束寻找增广路?出现短路时。

数组vd[i]记录到汇点距离为i的点出现的次数
若某时vd[i]变为0或者dis[源]>=n,表示出现断路。


代码:

const int inf=1000000000;
int g[201][201],vd[201],dis[201],m,n,x,y,z,flow,ans,i;
int dfs(int u,int flow)//搜索点u,从u的前一个点传过来的水流量大小为flow,也就是流入u的水量为flow

{     int v,temp,delta;
      if(u==n)return flow;//若u为汇点,表示找到增广路,返回可增广的流量值
      delta=0
;//delta记录从u流出去的水量
      for(v=1;v<=n;v++) //依次判断和u相连的点是否满足增广条件
         if(g[u][v]>0 && dis[u]==dis[v]+1) 
         {
             temp=dfs(v,min(flow-delta,g[u][v]));/搜索增广路,从u流向v的流量应该是flow和g[u][v]间的小者
             g[u][v]-=temp;
             g[v][u]+=temp;
             delta+=temp;//找到增广路后并不退回到源点重新增广,而是把增广值存在temp里,继续从u增广
             if(delta==flow||dis[1]>=n) return delta;//如果dis[1]>=n,说明源点无法到达汇点,结束搜索
         }//delta=flow说明u把流进它的水完全传了出去,表示已无可增广的流量,结束对u的增广
      vd[dis[u]]--;/若找不到增广路,把dis[u]+1,同时修改vd[]数组
      if(vd[dis[u]]==0)dis[1]=n;
      dis[u]=dis[u]+1;
      vd[dis[u]]++;
      return delta;
}
int main()
{     cin>>m>>n;    for(i=1;i<=m;i++) { cin>>x>>y>>z; g[x][y]+=z ;}
       while(dis[1]<n)
       {
            flow=dfs(1,inf);
            ans+=flow;
       }
       cout<<ans<<endl; return 0;
}


中等稠密图


稀疏图


稠密图


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值