网络流&&费用流模板
来源:互联网 发布:nicelabel 数据库密码 编辑:程序博客网 时间:2024/06/05 02:12
ISAP
1、有源有汇有上界无下界最大流 code1(邻接矩阵版):
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int map[201][201],n;int lev[201],pre[201],gap[201],cur[201]; int ISAP(int vs,int vt){memset(gap,0,sizeof(gap));memset(pre,-1,sizeof(pre));memset(lev,0,sizeof(lev));int i,v,u=pre[vs]=vs,aug,maxt=0,minl;gap[0]=vt;for (i=vs;i<=vt;++i) cur[i]=1;while (lev[vs]<vt) { for (v=cur[u];v<=vt;v++) if (lev[u]==lev[v]+1&&map[u][v]>0) {cur[u]=v; break;} if (v<=vt) { pre[v]=u; u=v; if (v==vt) { aug=2100000000; for (i=v;i!=vs;i=pre[i]) if (map[pre[i]][i]<aug) aug=map[pre[i]][i]; maxt+=aug; for (i=v;i!=vs;i=pre[i]) { map[pre[i]][i]-=aug; map[i][pre[i]]+=aug; } u=vs; } } else { minl=vt; for (v=1;v<=vt;++v) if (map[u][v]>0&&lev[v]<minl) minl=lev[v]; gap[lev[u]]--; if (gap[lev[u]]==0) break; lev[u]=minl+1; cur[u]=1; gap[lev[u]]++; u=pre[u]; } }return maxt;}int main(){int i,j;scanf("%d",&n);for (i=1;i<=n;++i) for (j=1;j<=n;++j) scanf("%d",&map[i][j]);printf("%d\n",ISAP(1,n));}
code2(next数组版):
#include<iostream>#include<cstdio>#include<cstring>#include<cstdio>using namespace std;struct hp{int u,v,c;}a[60000];int map[2000][2000];int point[2000],next[30000];int pre[30000],gap[2000],lev[2000],cur[2000];int ISAP(int vs,int vt){memset(lev,0,sizeof(lev));memset(gap,0,sizeof(gap));memset(pre,0,sizeof(pre));int i,v,u=vs,maxt=0,minl,aug,c;bool f=false;gap[0]=vt-vs+1;while (lev[vs]<vt) { f=false; for (v=cur[u];v!=0;v=next[v]) if (lev[u]==lev[a[v].v]+1&&a[v].c>0) {f=true; cur[u]=v; break;} if (f) { pre[a[v].v]=v; u=a[v].v; if (u==vt) { aug=2100000000; for (i=v;i!=0;i=pre[a[i].u]) if (a[i].c<aug) aug=a[i].c; maxt+=aug; for (i=v;i!=0;i=pre[a[i].u]) { a[i].c-=aug; a[i^1].c+=aug; } u=vs; } } else { minl=vt; for (i=point[u];i!=0;i=next[i]) if (minl>lev[a[i].v]&&a[i].c>0) minl=lev[a[i].v]; gap[lev[u]]--; if (gap[lev[u]]==0) break; lev[u]=minl+1; cur[u]=point[u]; gap[lev[u]]++;if (u!=vs) u=a[pre[u]].u; } }return maxt;}int main(){int i,n,j,c,e=1;scanf("%d",&n);for (i=1;i<=n;++i) for (j=1;j<=n;++j) { scanf("%d",&c); if (c!=0) { e++; a[e].u=i; a[e].v=j; a[e].c=c; next[e]=point[i]; cur[i]=point[i]=e; e++; a[e].u=j; a[e].v=i; a[e].c=0; next[e]=point[j]; cur[j]=point[j]=e; } } printf("%d\n",ISAP(1,n));}
2、(1)多源多汇有上界无下界最大流 ,设置一个超级源点,流向所有入度为0的原源点,容量为无穷,再设置一个超级汇点,使所有出度为0的原汇点,容量为无穷。求一遍最大流即可。
(2)有源有汇有点界的最大流,对每个点插成两个点,求一遍最大流即可。
3、无源无汇有上界有下界最大流:构图时,依然设置超级源点和超级汇点,但如果该节点的下界是净流出(下界的出度减入度>0)的话,该点到超级汇点的权等于净流出量;如果该节点的下界是净流入的话(该点的出度减入度<0)的话,超级源点到该点的权等于净流入量。求一遍最大流,如果超级源点的出度满流的话,即存在最大流,输出即可。否则则不存在最大流 code:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int map[150][150],n;int lev[150],pre[150],gap[150];int ISAP(int vs,int vt){memset(lev,0,sizeof(lev));memset(gap,0,sizeof(gap));memset(pre,-1,sizeof(pre));int i,v,u=pre[vs]=vs,minl,aug,maxt=0;gap[0]=vt-vs+1;while (lev[vs]<vt) { for (v=vs;v<=vt;v++) if (map[u][v]>0&&lev[u]==lev[v]+1) break; if (v<=vt) { pre[v]=u; u=v; if (v==vt) { aug=2100000000; for (i=v;i!=vs;i=pre[i]) if (map[pre[i]][i]<aug) aug=map[pre[i]][i]; maxt+=aug; for (i=v;i!=vs;i=pre[i]) { map[pre[i]][i]-=aug; map[i][pre[i]]+=aug; } u=vs; } } else { minl=vt; for (v=vs;v<=vt;++v) if (map[u][v]>0&&lev[v]<minl) minl=lev[v]; gap[lev[u]]--; if (gap[lev[u]]==0) break; lev[u]=minl+1; gap[lev[u]]++; u=pre[u]; } }return maxt;}int main(){int i,j,m,inf,outf,sum,ans,p=0;int pic[150][150][2];scanf("%d",&n);for (i=1;i<=n;++i) for (j=1;j<=2*n;++j) scanf("%d",&pic[i][(j+1)/2][1-j%2]);for (i=1;i<=n;++i) { inf=0; outf=0; for (j=1;j<=n;++j) { inf+=pic[j][i][0]; outf+=pic[i][j][0]; map[i][j]=pic[i][j][1]-pic[i][j][0]; }sum=outf-inf;if (sum<0) { map[0][i]=abs(sum); p+=abs(sum); }else map[i][n+1]=abs(sum); } ans=ISAP(0,n+1); if (ans==p) printf("%d\n",ans); else printf("0\n"); }4、有源有汇有上界有下界最大流,使汇点到源点有一条上界为无穷,下界为0的边(注意,此边在构图之后加),使它变为无源无汇图,构图和判断同无源无汇有上界有下界最大流,但输出时,先删去汇点到源点的无穷边,再跑一遍原源点到原汇点的最大流,输出即可 code:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int map[150][150],n;int lev[150],pre[150],gap[150];int ISAP(int vs,int vt){memset(lev,0,sizeof(lev));memset(gap,0,sizeof(gap));memset(pre,-1,sizeof(pre));int i,v,u=pre[vs]=vs,minl,aug,maxt=0;gap[0]=vt-vs+1;while (lev[vs]<vt) { for (v=vs;v<=vt;v++) if (map[u][v]>0&&lev[u]==lev[v]+1) break; if (v<=vt) { pre[v]=u; u=v; if (v==vt) { aug=2100000000; for (i=v;i!=vs;i=pre[i]) if (map[pre[i]][i]<aug) aug=map[pre[i]][i]; maxt+=aug; for (i=v;i!=vs;i=pre[i]) { map[pre[i]][i]-=aug; map[i][pre[i]]+=aug; } u=vs; } } else { minl=vt; for (v=vs;v<=vt;++v) if (map[u][v]>0&&lev[v]<minl) minl=lev[v]; gap[lev[u]]--; if (gap[lev[u]]==0) break; lev[u]=minl+1; gap[lev[u]]++; u=pre[u]; } }return maxt;}int main(){int i,j,m,inf,outf,sum,ans,p=0;int pic[150][150][2];scanf("%d",&n);for (i=1;i<=n;++i) for (j=1;j<=2*n;++j) scanf("%d",&pic[i][(j+1)/2][1-j%2]);for (i=1;i<=n;++i) { inf=0; outf=0; for (j=1;j<=n;++j) { inf+=pic[j][i][0]; outf+=pic[i][j][0]; map[i][j]=pic[i][j][1]-pic[i][j][0]; }sum=outf-inf;if (sum<0) { map[0][i]=abs(sum); p+=abs(sum); }else map[i][n+1]=abs(sum); } map[n][1]=2100000000; ans=ISAP(0,n+1); if (ans==p) { map[n][1]=0; ans=ISAP(1,n); printf("%d\n",ans); } else printf("0\n"); }
5、费用流模板,先跑一遍最短路,再在最短路上进行增广,ans+=dis(vs,vt)*maxflow,直到无法求出最短路。输出ans即可。code:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int point[101],next[5000],queue[500],dis[101],minn[101],pre[101],e,head,tail,ans=0,n,st,en;bool exist[101];struct hp{int u,v,c,w;}a[5000];void add(int u,int v,int c,int w){e++;a[e].u=u; a[e].v=v; a[e].c=c; a[e].w=w; next[e]=point[u]; point[u]=e;e++;a[e].u=v; a[e].v=u; a[e].c=0; a[e].w=0-w; next[e]=point[v]; point[v]=e;}bool work(int vs,int vt){memset(exist,false,sizeof(exist));memset(dis,127,sizeof(dis));memset(pre,0,sizeof(pre)); int i,j,u,stan=dis[1]; minn[vs]=dis[1]; exist[vs]=true; dis[vs]=0; head=0; tail=1; queue[tail]=vs;while (head!=tail) { head=head%500+1;u=queue[head];exist[u]=false;for (i=point[u];i!=0;i=next[i]) { if (a[i].c>0&&dis[a[i].v]>dis[u]+a[i].w) { dis[a[i].v]=dis[u]+a[i].w; pre[a[i].v]=i; minn[a[i].v]=min(minn[u],a[i].c); if (!exist[a[i].v]) { tail=tail%500+1; queue[tail]=a[i].v; exist[a[i].v]=true; } } } }if (dis[vt]==stan) return false;ans+=dis[vt]*minn[vt];for (i=pre[vt];i!=0;i=pre[a[i].u]) { a[i].c-=minn[vt]; a[i^1].c+=minn[vt]; }return true;}int main(){int i,j,c,w;scanf("%d%d%d",&n,&st,&en);e=1;for (i=1;i<=n;++i) for (j=1;j<=n;++j) { scanf("%d%d",&c,&w); if (c) add(i,j,c,w); } while (work(st,en));printf("%d\n",ans);}
最大权闭合子图code:
#include<iostream>#include<cstdio>#include<cstring>#define inf 2100000000using namespace std;struct hp{int u,v,c;}a[500000];int e,n,m;int p[5001];int point[56000],next[500000],pre[56000],lev[56000],gap[56000];int ISAP(int vs,int vt){int v,i,u,maxf=0,aug,minl; bool f;gap[0]=vt-vs+1; u=vs;while (lev[vs]<vt) { f=false;for (v=point[u];v!=0;v=next[v]) if (lev[u]==lev[a[v].v]+1&&a[v].c>0) {f=true; break;}if (f) { pre[a[v].v]=v; u=a[v].v; if (u==vt) { aug=inf; for (i=v;i!=0;i=pre[a[i].u]) if (aug>a[i].c) aug=a[i].c; maxf+=aug; for (i=v;i!=0;i=pre[a[i].u]) { a[i].c-=aug; a[i^1].c+=aug; } u=vs; } }else { minl=vt;for (i=point[u];i!=0;i=next[i]) if (minl>lev[a[i].v]&&a[i].c>0) minl=lev[a[i].v]; gap[lev[u]]--;if (gap[lev[u]]==0) break;lev[u]=minl+1;gap[lev[u]]++;if (u!=vs) u=a[pre[u]].u; } }return maxf;}int main(){int i,x,y,c,ans,sum=0;freopen("profit9.in","r",stdin);freopen("profit.out","w",stdout);scanf("%d%d",&n,&m);e=1;for (i=1;i<=n;++i) { scanf("%d",&p[i]); e++; next[e]=point[i]; point[i]=e; a[e].u=i; a[e].v=n+m+1; a[e].c=p[i]; e++; next[e]=point[n+m+1]; next[n+m+1]=e; a[e].u=n+m+1; a[e].v=i; a[e].c=0; }for (i=1;i<=m;++i) { scanf("%d%d%d",&x,&y,&c); sum+=c;e++;next[e]=point[0]; point[0]=e; a[e].u=0; a[e].v=n+i; a[e].c=c;e++;next[e]=point[n+i]; point[n+i]=e; a[e].u=n+i; a[e].v=0; a[e].c=0;e++;next[e]=point[n+i]; point[n+i]=e; a[e].u=n+i; a[e].v=x; a[e].c=inf;e++;next[e]=point[x]; point[x]=e; a[e].u=x; a[e].v=n+i; a[e].c=0; e++; next[e]=point[n+i]; point[n+i]=e; a[e].u=n+i; a[e].v=y; a[e].c=inf; e++; next[e]=point[y]; point[y]=e; a[e].u=y; a[e].v=n+i; a[e].c=0; } ans=ISAP(0,n+m+1); printf("%d\n",sum-ans); fclose(stdin); fclose(stdout);}
0 0
- 网络流&&费用流模板
- 网络流&&费用流模板(OrzLcomyn神犇的模板)
- 费用流模板
- 费用流 模板 MCMF
- 费用流模板
- ZKW费用流 模板
- 费用流模板
- 费用流 模板
- 费用流模板
- zkw费用流模板
- 【最小费用流】【模板】
- 【模板】费用流
- 最小费用流模板
- 费用流模板
- 最小费用流模板
- SPFA费用流模板
- zkw费用流模板
- 费用流模板 hdu1533
- codeforces 13C. Sequence
- 双向循环链表
- Unity3D 游戏开发之提示栏的工作实现详解
- Tessellation Shader 随笔
- Unity3D技术之FBX 导出指南
- 网络流&&费用流模板
- Android中使用Handler引发的内存泄露
- vmware 虚拟机使用redhat,出现 connect: Network is unreachable解決方法
- 自定义九宫格控件NineGridLayout ,实现微信朋友圈图片九宫格显示
- Understanding GPU Derivatives(ddx,ddy)
- java中的对象转换
- HDU -- 1863 畅通工程 (mst)
- Java --乘方
- Unity3D技术之小地图的制作详解