无源汇上下界网络流 zju zoj 2314
2012-02-29 16:24
204 查看
类型:无源汇可行流
参考自()
http://hi.baidu.com/evelynhe/blog/item/f1c5ba2fcbe674271e3089ad.html
每条边的容量满足一定的限制,即有一个上限值,也有一个下限值
上界用ci表示,下界用bi表示。
下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– bi。
主要思想:每一个点流进来的流=流出去的流
对于每一个点i,令
Mi= sum(i点所有流进来的下界流)– sum(i点所有流出去的下界流)
如果Mi大于0,代表此点必须还要流出去Mi的自由流,那么我们从源点连一条Mi的边到该点。
如果Mi小于0,代表此点必须还要流进来Mi的自由流,那么我们从该点连一条Mi的边到汇点。
如果求S->T的最大流,看是否满流(S的相邻边都流满)。
满流则有解,否则无解。
View Code
参考自()
http://hi.baidu.com/evelynhe/blog/item/f1c5ba2fcbe674271e3089ad.html
每条边的容量满足一定的限制,即有一个上限值,也有一个下限值
上界用ci表示,下界用bi表示。
下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– bi。
主要思想:每一个点流进来的流=流出去的流
对于每一个点i,令
Mi= sum(i点所有流进来的下界流)– sum(i点所有流出去的下界流)
如果Mi大于0,代表此点必须还要流出去Mi的自由流,那么我们从源点连一条Mi的边到该点。
如果Mi小于0,代表此点必须还要流进来Mi的自由流,那么我们从该点连一条Mi的边到汇点。
如果求S->T的最大流,看是否满流(S的相邻边都流满)。
满流则有解,否则无解。
View Code
#include<stdio.h> #include<string.h> const int MAX=100005; const int INF=1000000000; struct EDGE { int v,c,next; }edge[1000000]; int E,head[MAX]; int gap[MAX],cur[MAX]; int pre[MAX],dis[MAX]; int in[225],low[50000]; void add_edge(int s,int t,int c,int cc) { edge[E].v=t; edge[E].c=c; edge[E].next=head[s]; head[s]=E++; edge[E].v=s; edge[E].c=cc; edge[E].next=head[t]; head[t]=E++; } int min(int a,int b){return (a==-1||b<a)?b:a;} int SAP(int s,int t,int n) { memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); int i; for(i=0;i<n;i++)cur[i]=head[i]; int u=pre[s]=s,maxflow=0,aug=-1,v; gap[0]=n; while(dis[s]<n) { loop: for(i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(edge[i].c>0&&dis[u]==dis[v]+1) { aug=min(aug,edge[i].c); pre[v]=u; cur[u]=i; u=v; if(u==t) { for(u=pre[u];v!=s;v=u,u=pre[u]) { edge[cur[u]].c-=aug; edge[cur[u]^1].c+=aug; } maxflow+=aug; aug=-1; } goto loop; } } int mindis=n; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(edge[i].c>0&&dis[v]<mindis) { cur[u]=i; mindis=dis[v]; } } if((--gap[dis[u]])==0)break; gap[dis[u]=mindis+1]++; u=pre[u]; } return maxflow; } bool solve(int n) { for(int i=1;i<=n;i++) { if(in[i]>0) add_edge(0,i,in[i],0); if(in[i]<0) add_edge(i,n+1,-in[i],0); } SAP(0,n+1,n+2); for(int i=head[0];i!=-1;i=edge[i].next)//从源点出发的边都满流 { if(edge[i].c) return false; } return true; } int main() { int t,n,m,a,b,c; scanf("%d",&t); while(t--) { E=0; memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d%d%d",&a,&b,&low[i],&c); in[a]-=low[i],in[b]+=low[i]; add_edge(a,b,c-low[i],0); } if(solve(n)) { printf("YES\n"); for(int i=0;i<m;i++) printf("%d\n",edge[(i<<1)^1].c+low[i]);//反向的流即自由流,再加上下界的流 } else printf("NO\n"); puts(""); } return 0; }
相关文章推荐
- 无源汇上下界网络流 zju zoj 2314
- ZOJ 2314 Reactor Cooling(无源汇上下界网络流)
- ZOJ 2314 Reactor Cooling 上下界网络流(无源汇可行流)
- ZOJ 2314 Reactor Cooling 无源汇上下界网络流 可行流
- ZOJ 2314 Reactor Cooling [无源汇上下界网络流]
- ZOJ 2314 Reactor Cooling 上下界网络流(无源汇可行流)
- 无源无汇上下界网络流(循环流) ZOJ 2314 Reactor Cooling
- zoj 2314 reactor cooling(无源汇有上下界可行流)
- 网络流之上下界网络流zoj zju 3229
- 【有上下界网络流】【ZOJ】2314 Reactor Cooling
- zoj 2314 Reactor Cooling--无源汇有上下界最大流--递归sap
- zoj 2314 Reactor Cooling (无源汇有上下界的可行流)
- ZOJ 2314 有上下界的网络流
- ZOJ 2314 有上下界的网络流
- zoj 2314 Reactor Cooling(无源汇上下界的可行流)
- [ZOJ 2314]Reactor Cooling(有上下界的网络流)
- ZOJ 2314 Reactor Cooling 无源汇上下界网络流
- 【无源汇有上下界可行流】ZOJ-2314 Reactor Cooling
- ZOJ 2314 有上下界的网络流
- zoj 2314 Reactor Cooling (有上下界的网络流)