ZOJ_2314_Reactor Cooling_有上下界可行流模板
ZOJ_2314_Reactor Cooling_有上下界可行流模板
The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear reactor to produce plutonium for the nuclear bomb they are planning to create. Being the wicked computer genius of this group, you are responsible for developing the cooling system for the reactor.
The cooling system of the reactor consists of the number of pipes that special cooling liquid flows by. Pipes are connected at special points, called nodes, each pipe has the starting node and the end point. The liquid must flow by the pipe from its start point to its end point and not in the opposite direction.
Let the nodes be numbered from 1 to N. The cooling system must be designed so that the liquid is circulating by the pipes and the amount of the liquid coming to each node (in the unit of time) is equal to the amount of liquid leaving the node. That is, if we designate the amount of liquid going by the pipe from i-th node to j-th as fij, (put fij = 0 if there is no pipe from node i to node j), for each i the following condition must hold:
Each pipe has some finite capacity, therefore for each i and j connected by the pipe must be fij <= cij where cij is the capacity of the pipe. To provide sufficient cooling, the amount of the liquid flowing by the pipe going from i-th to j-th nodes must be at least lij, thus it must be fij >= lij.
Given cij and lij for all pipes, find the amount fij, satisfying the conditions specified above.
This problem contains multiple test cases!
The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.
The output format consists of N output blocks. There is a blank line between output blocks.
Input
The first line of the input file contains the number N (1 <= N <= 200) - the number of nodes and and M - the number of pipes. The following M lines contain four integer number each - i, j, lij and cij each. There is at most one pipe connecting any two nodes and 0 <= lij <= cij <= 10^5 for all pipes. No pipe connects a node to itself. If there is a pipe from i-th node to j-th, there is no pipe from j-th node to i-th.
Output
On the first line of the output file print YES if there is the way to carry out reactor cooling and NO if there is none. In the first case M integers must follow, k-th number being the amount of liquid flowing by the k-th pipe. Pipes are numbered as they are given in the input file.
Sample Input
2
4 6
1 2 1 2
2 3 1 2
3 4 1 2
4 1 1 2
1 3 1 2
4 2 1 2
4 6
1 2 1 3
2 3 1 3
3 4 1 3
4 1 1 3
1 3 1 3
4 2 1 3
Sample Input
NO
YES
1
2
3
2
1
1
题意就是每条边有流量范围[L,R],问是否存在一种方案使得所有边上的流量都符合题意。
如果存在这样的方案需要输出方案。
考虑先强制让每条边流L的流量,这样每条边相当于有一个容量为R-L。
新建S,T。有一条边(x,y,l,r),连这样的边x->y(r-l), S->y(l), x->T(l),保证至少l流量。
然后跑出最大流,判断最大流是否等于l的和(S流出去的流量之和)。
每条边的实际流量就是残量+L。
但是这样做可能一个点连出去多条边,然后每次都连边就相当于S到x连了很多条边,这样显然非常sb。
于是可以记录一下每个点应该出去多少流量,如果是正的则连S,负的则连T。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 205 #define M 200050 #define S (n+1) #define T (n+2) #define inf 100000000 int head[N],to[M],nxt[M],cnt=1,flow[M],xx[M],yy[M],ll[M],rr[M],in[N]; int dep[N],Q[N],l,r,sum,n,m; inline void add( int u, int v, int f) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; } bool bfs() { memset (dep,0, sizeof (dep)); dep[S]=1;l=r=0;Q[r++]=S; while (l<r) { int x=Q[l++],i; for (i=head[x];i;i=nxt[i]) { if (!dep[to[i]]&&flow[i]) { dep[to[i]]=dep[x]+1; if (to[i]==T) return 1; Q[r++]=to[i]; } } } return 0; } int dfs( int x, int mf) { int i,nf=0; if (x==T) return mf; for (i=head[x];i;i=nxt[i]) { if (dep[to[i]]==dep[x]+1&&flow[i]) { int tmp=dfs(to[i],min(mf-nf,flow[i])); if (!tmp) dep[to[i]]=0; nf+=tmp; flow[i]-=tmp; flow[i^1]+=tmp; if (nf==mf) break ; } } return nf; } void dinic() { int f,i; while (bfs()) while (f=dfs(S,inf)) sum-=f; if (!sum) { puts ( "YES" ); for (i=1;i<=m;i++) { printf ( "%d\n" ,ll[i]+flow[2*i+1]); } } else { puts ( "NO" ); } puts ( "" ); } void solve() { memset (head,0, sizeof (head)); memset (in,0, sizeof (in)); cnt=1; sum=0; scanf ( "%d%d" ,&n,&m); int i; for (i=1;i<=m;i++) { scanf ( "%d%d%d%d" ,&xx[i],&yy[i],&ll[i],&rr[i]); add(xx[i],yy[i],rr[i]-ll[i]); in[xx[i]]-=ll[i]; in[yy[i]]+=ll[i]; } for (i=1;i<=n;i++) { if (in[i]>0) add(S,i,in[i]),sum+=in[i]; else if (in[i]<0) add(i,T,-in[i]); } dinic(); } int main() { int t; scanf ( "%d" ,&t); while (t--) solve(); } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· DeepSeek V3 两周使用总结
· 回顾我的软件开发经历(1)
· C#使用yield关键字提升迭代性能与效率
· 低成本高可用方案!Linux系统下SQL Server数据库镜像配置全流程详解
· 4. 使用sql查询excel内容