注释应该比较清楚了吧= =
#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()); }
时间: 2024-10-09 23:23:17