您的位置:首页 > 其它

最大流ISAP算法(邻接表)模板

2010-05-29 21:47 323 查看
const int maxn=201;

const int maxm=201;

struct node

{

int x,y,f,op,next; //x起点,y终点,f权值,next是以x为起点的上一条边在g中的位置,op是反向边在g中的下标位置

}g[maxm*2];

//first[]存储的是以x为起点的最后一条边的在数组g中的下标

//sumd[]用于记录表示标号为i的顶点数有多少个,用于间隙优化

int first[maxn],now[maxn],sumd[maxn];

int ncount; //代表结点的总数

int dis[maxn],fanhui[maxn],pre[maxn],tot; //dis[]用于记录距离标号,pre[i]记录i的前驱在g[]中的位置,tot记录边的总数

void add(int x,int y,int c)

{

tot++; //tot记录边的总数

g[tot].x=x;

g[tot].y=y;

g[tot].f=c;

g[tot].op=tot+1; //反向边在g中的下标位置

g[tot].next=first[x]; //记录以x为起点的上一条边在g中的下标位置

first[x]=tot; //以x为起点的边的位置

tot++;

//反向边

g[tot].x=y;

g[tot].y=x;

g[tot].f=0; //反向边的初始网络流为0

g[tot].op=tot-1;

g[tot].next=first[y];

first[y]=tot;

}

//ISAP算法

int maxflow(int src,int des)

{

int i,flow,t,j,tempmin; //i,j用于标识结点,t用于标识结点在g中的位置

bool flag; //用于标识是否找到了允许路径

int sumFlow;

memset(dis,0,sizeof(dis));

memset(sumd,0,sizeof(sumd));

for(i=1;i<=ncount;i++) //遍历所有的结点

now[i]=first[i];

sumd[0]=ncount; //标号为0的结点有ncount个

  sumFlow=0; //sumFlow记录最大流,初始化为0

i=src; //i初始化为起点

  flow=10000000;

while(dis[src]<ncount)

{

fanhui[i]=flow;

flag=false;

t=now[i];

while(t!=0) //寻找允许路径

{

j=g[t].y;

if((g[t].f>0)&&(dis[j]+1==dis[i])) //允许弧

{

flag=true;

pre[j]=t;

now[i]=t;

if(g[t].f<flow) //找到允许增量

flow=g[t].f;

i=j;

if(i==des) //找到了允许路径

{

sumFlow+=flow;

while(i!=src) //修改残余网络

{

g[pre[i]].f-=flow; //正向边

g[g[pre[i]].op].f+=flow; //反向边

i=g[pre[i]].x;

}

flow=10000000;

}

break;

}

t=g[t].next;

}

if(flag)

continue;

//没有找到允许路径

tempmin=ncount-1;

t=first[i];

while(t!=0)

{

if((g[t].f>0)&&(dis[g[t].y]<tempmin))

{

tempmin=dis[g[t].y];

now[i]=t;

}

t=g[t].next;

}

sumd[dis[i]]--;

if(sumd[dis[i]]==0) break; //间隙优化

dis[i]=tempmin+1; //此处别忘+1,因为d[i]=tempmin{d[j]+1|(i,j)在残留网络中}

sumd[dis[i]]++;

if(i!=src)

{

i=g[pre[i]].x;

flow=fanhui[i];

}

}

return sumFlow;

}

int main()

{

int src,des; //src是起点,des是终点

memset(first,0,sizeof(first)); //初始化first

tot = 0; //tot初始化为0

ncount = n;        //初始化ncount为结点总数

for(i=0;i<N;++i)

{

cin>>x>>y>>c;

add(x,y,c);

}

printf("%d\n",maxflow(src,des));

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: