设为首页 收藏本站
查看: 830|回复: 0

[经验分享] 网络流sap算法模版

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-9-21 10:23:13 | 显示全部楼层 |阅读模式
  递归版sap:



#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 310
#define M 50010
#define inf 1<<30
using namespace std;
struct Edge{
int to,val,next;
}edge[M];
int index[N],d[N],gap[N],e;
void addedge(int from,int to,int val)
{
edge[e].to=to;
edge[e].val=val;
edge[e].next=index[from];
index[from]=e++;
edge[e].to=from;
edge[e].val=0;
edge[e].next=index[to];
index[to]=e++;
}
int source,des,n,m;
int dfs(int pos,int flow)
{
if(pos==des)
return flow;
int i,j,v,val,lv,mind,c;
mind=n-1;//初始最小标号为n-1
lv=flow;
for(i=index[pos];i!=-1;i=edge.next)
{
v=edge.to;
val=edge.val;
if(val)
{
if(d[v]+1==d[pos])
{
c=min(lv,val);//对于该点的最小可行流
c=dfs(v,c);
edge.val-=c;//更新剩余图
edge[i^1].val+=c;
lv-=c;
if(d[source]>=n)return flow-lv;
if(lv==0) break;
}
if(d[v]<mind)mind=d[v];//找出与pos相连的点的最小标号
        }
}
if(lv==flow)//没有找到增广路劲,进行标号更新
    {
--gap[d[pos]];
if(!gap[d[pos]])
d[source]=n;
d[pos]=mind+1;
++gap[d[pos]];
}
return flow-lv;
}
int sap(int st,int de)
{
source=st;
des=de;
memset(d,0,sizeof(d));
memset(gap,0,sizeof(gap));
gap[0]=n;//初始标号为0的有n个.
int ans=0;
while(d[st]<n)//n是图中点的个数     {
ans+=dfs(st,inf);
//cout<<d[st]<<endl;
    }
return ans;
}
void init()
{
e=0;
memset(index,-1,sizeof(index));
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
int i;
int ll,rr,cap;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&ll,&rr,&cap);
addedge(ll,rr,cap);
}
printf("%d\n",sap(1,n));     }
return 0;
}
  非递归版sap:



#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define Maxn 6010
#define Maxm 200000
#define LL __int64
#define Abs(a) (a)>0?(a):(-a)
using namespace std;
struct Edge{
int from,to,next;
LL val;
}edge[Maxm];
int index[Maxn],d[Maxn],gap[Maxn],e,vi[Maxn],n,m;
LL value[Maxn];
LL inf=0;
inline void addedge(int from,int to,LL val)//有向边
{
edge[e].from=from;
edge[e].to=to;
edge[e].val=val;
edge[e].next=index[from];
index[from]=e++;
edge[e].from=to;
edge[e].to=from;
edge[e].val=0;
edge[e].next=index[to];
index[to]=e++;
}
int prev[Maxn],curr[Maxn];
LL sap(int src,int des,int N)//分别为起点源点和点的数目
{
bool flag;
int u=src;
LL cnt=inf,sum=0;
memset(d,0,sizeof(d));
memset(gap,0,sizeof(gap)); gap[0]=N;
while(d[src]!=N)
{
flag=false;
for(int i=index;i!=-1;i=edge.next)
{
if(edge.val&&d[edge.to]==d-1)
{
cnt=min(cnt,edge.val);
prev[edge.to]=u;
curr[edge.to]=i;
u=edge.to;
flag=true;
if(u==des)
{
while(u!=src)
{
edge[curr].val-=cnt;
edge[curr^1].val+=cnt;
u=prev;
}
sum+=cnt;
cnt=inf;
}
else break;
}
}
if(!flag)
{
if(!--gap[d]) break;
else
{
d=N;
for(int i=index;i!=-1;i=edge.next)
{
if(edge.val) d=min(d,d[edge.to]+1);
}
gap[d]++;
if(u!=src) u=prev;
}
}
}
return sum;
}
void init()
{
e=0;
inf=0;
memset(index,-1,sizeof(index));
memset(vi,0,sizeof(vi));
}
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-116635-1-1.html 上篇帖子: SAP流水号 下篇帖子: SAP标准教材名称所代表的模块和含义(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表