[gotoac]网络流SAP(邻接表&邻接矩阵) beta2

来源:互联网 发布:外星人论坛源码 编辑:程序博客网 时间:2024/05/21 08:41
#define getmin(x,y) (x= (x<0 || (y)<x)? (y):x)
struct sap{//动态邻接表typedef int type;     //流量的类型struct edge{int from,to;type flow;   //该条边的剩余流量edge(int u=0,int v=0,type f=0){from=u,to=v,flow=f;}};int n,m;              //顶点数,边数(包括反向弧)int dis[M],cur[M];    //从起点到i的距离,当前所在的弧int gap[M],pre[M];    //距离标号计数,可增广路上的上一条弧的序号vector<edge>edg;      //边表vector<int>g[M];      //g[i][j]表示点i连接的第j条边的序号void init(int _n){    //初始化n=_n,edg.clear();for(int i=0;i<n;i++) g[i].clear();}void insert(int u,int v,type c){edg.push_back(edge(u,v,c)),edg.push_back(edge(v,u,0));m=edg.size();g[u].push_back(m-2),g[v].push_back(m-1);}type maxFlow(int s,int t){type res=0,a;clr(dis,0,n),clr(gap,0,n),clr(cur,0,n);gap[0]=n;for(int u=s;dis[s]<n;){if(u==t){//增广for(a=-1;u!=s;u=edg[pre[u]].from)getmin(a,edg[pre[u]].flow);for(u=t;u!=s;u=edg[pre[u]].from)edg[pre[u]].flow-=a,edg[pre[u]^1].flow+=a;res+=a;}bool ok=0;for(int i=cur[u];i<g[u].size();i++){//前推edge& e=edg[g[u][i]];if(dis[u]==dis[e.to]+1 && e.flow>0){pre[e.to]=g[u][i],cur[u]=i,u=e.to;ok=1;break;}}if(!ok){//回退int mindis=n-1;for(int i=0;i<g[u].size();i++){edge& e=edg[g[u][i]];if(e.flow>0 && mindis>dis[e.to])mindis=dis[e.to],cur[u]=i;}if(--gap[dis[u]]==0) break;gap[dis[u]=mindis+1]++;if(u!=s) u=edg[pre[u]].from;}}return res;}};


struct sap{//静态邻接表typedef int type;struct edge{int v,next;type flow;}edg[999999];     //边表int head[M];      //邻接表int n,m;          //顶点数,边数int cur[M],dis[M];//当前弧,距离标号int pre[M],gap[M];//上一点,间隙优化void init(int _n){n=_n,m=0,clr(head,-1,n);}void insert(int u,int v,type f,type c=0){edg[m].flow=f,edg[m].v=v;edg[m].next=head[u],head[u]=m++;edg[m].flow=0,edg[m].v=u;edg[m].next=head[v],head[v]=m++;}type maxFlow(int s,int t){type res=0,a;int i;for(i=0;i<n;i++) cur[i]=head[i];clr(gap,0,n),clr(dis,0,n);gap[0]=n,pre[s]=s;for(int u=s;dis[s]<n;){if(u==t){for(a=-1;u!=s;u=pre[u])getmin(a,edg[cur[pre[u]]].flow);for(u=t;u!=s;u=pre[u]){edg[cur[pre[u]]].flow-=a;edg[cur[pre[u]]^1].flow+=a;}res+=a;}bool ok=0;for(i=cur[u];i!=-1;i=edg[i].next){edge& e=edg[i];if(dis[u]==dis[e.v]+1 && e.flow>0){pre[e.v]=u,cur[u]=i,u=e.v,ok=1;break;}}if(!ok){int mindis=n-1;for(i=head[u];i!=-1;i=edg[i].next){edge& e=edg[i];if(mindis>dis[e.v] && e.flow>0)mindis=dis[e.v],cur[u]=i;}if(--gap[dis[u]]==0) break;gap[dis[u]=mindis+1]++;u=pre[u];}}return res;}};

 


struct sap{//邻接矩阵typedef int type;     //流量的类型int n;                //顶点数type flow[M][M];      //该条边的剩余流量int dis[M],cur[M];    //从起点到i的距离,当前所在的弧int gap[M],pre[M];    //距离标号计数,可增广路上的上一个点void init(int _n){    //初始化n=_n;for(int i=0;i<n;i++)for(int j=0;j<n;j++)flow[i][j]=0;}void insert(int u,int v,double f){flow[u][v]=f;}type maxFlow(int s,int t){clr(dis,0,n),clr(gap,0,n),clr(cur,0,n);gap[0]=n,pre[s]=s;type a,res=0;for(int u=s;dis[s]<n;){if(u==t){for(a=-1;u!=s;u=pre[u])getmin(a,flow[pre[u]][u]);for(u=t;u!=s;u=pre[u])flow[pre[u]][u]-=a,flow[u][pre[u]]+=a;res+=a;}bool ok=0;for(int v=cur[u];v<n;v++){if(dis[u]==dis[v]+1 && flow[u][v]>0){pre[v]=u,cur[u]=v,u=v;ok=1;break;}}if(!ok){int mindis=n-1;for(int v=0;v<n;v++)if(flow[u][v]>0 && mindis>dis[v])mindis=dis[v],cur[u]=v;if(--gap[dis[u]]==0) break;gap[dis[u]=mindis+1]++,u=pre[u];}}return res;}};

原创粉丝点击