【整合】网络流ISAP算法模板

来源:互联网 发布:手持数据终端 编辑:程序博客网 时间:2024/04/29 06:26
注释应该比较清楚了吧= =
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 2048#define MAXINT 0x7fffffffusing namespace std;int n,m;//点的数目和边的数目int dis[MAXN+1];//距离标号 int num[MAXN+1];int src,des;//src源点,des汇点 int u,v,w;struct edge{int f; int c;int ver;edge *rev;edge *next;edge(){};edge(int v,int cap,edge *nex):ver(v),c(cap),next(nex),rev(NULL),f(0){};void* operator new(size_t, void *p){ return p; }}*s[MAXN+1];void init(){int queue[MAXN+1],head=0,tail=0;for (int i=1;i<=n;i++)    dis[i]=MAXN,num[i]=0;queue[tail++]=des;dis[des]=0;num[0]=1;while (head!=tail){int v=queue[head++];edge *e=s[v];while (e){if ((e->rev)&&(e->rev->c==0)||dis[e->ver]<MAXN) {}//若改点后的边不可通过//流或者已经更新就无需更新else {dis[e->ver]=dis[v]+1;++num[dis[e->ver]];queue[tail++]=e->ver;}e=e->next;}}}int maxflow()//ISAP算法实现过程 {int st=src,ret=0;edge *E[MAXN],*rep[MAXN];for (int i=1;i<=n;i++) E[i]=s[i];while (dis[src]<n)//不存在增广路径就停止 {if (st==des)//找到了增广路径 {int delta=MAXINT;for (int i=src;i!=des;i=E[i]->ver)delta=min(delta,E[i]->c);for (int i=src;i!=des;i=E[i]->ver){E[i]->c-=delta;E[i]->f+=delta;E[i]->rev->c+=delta;E[i]->rev->f-=delta;}ret+=delta;st=src;}edge *e;for (e=E[st];e;e=e->next)if (e->c>0&&dis[st]==dis[e->ver]+1) break;if (e)//存在允许弧 {E[st]=e;rep[e->ver]=e->rev;st=e->ver;}else{if ((--num[dis[st]])==0) break;//GAP优化 E[st]=s[st];int mind=n;for (edge *t=s[st];t;t=t->next)if (t->c>0)    mind=min(mind,dis[t->ver]);dis[st]=mind+1;++num[dis[st]];if (st!=src) st=rep[st]->ver;}    }return ret;}int main(){freopen("ditch.in","r",stdin);freopen("ditch.out","w",stdout);scanf("%d%d",&m,&n);src=1,des=n;edge *buffer=new edge[2*m]; edge *data=buffer;while (m--){scanf("%d%d%d",&u,&v,&w);s[u]=new((void*) data++) edge(v,w,s[u]);s[v]=new((void*) data++) edge(u,0,s[v]);s[u]->rev=s[v];s[v]->rev=s[u];}init();printf("%d",maxflow());}
1 0
原创粉丝点击