[置顶]【整合】网络流ISAP算法模板
- 注释应该比较清楚了吧= =
注释应该比较清楚了吧= =
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #define MAXN 2048
- #define MAXINT 0x7fffffff
- using 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());
- }
- 注释应该比较清楚了吧= =
注释应该比较清楚了吧= =
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #define MAXN 2048
- #define MAXINT 0x7fffffff
- using 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());
- }