zoukankan      html  css  js  c++  java
  • 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:

    f i,1+f i,2+...+f i,N = f 1,i+f 2,i+...+f N,i

    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。

     

    代码:

    #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
    ",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();
    }
    

     

  • 相关阅读:
    wp7订餐客户端源码
    AOP技术术语
    urlpattern详解
    .net 访问IBM DB2 数据库
    入驻博客园
    hadoop视频
    阿里OneData构建数据指标体系
    大数据领域全景解析
    PyTorch中梯度为什么默认自动累加,在反向传播前要手动将梯度清零?
    Pytorch:Dataloader和Dataset以及搭建数据部分的步骤
  • 原文地址:https://www.cnblogs.com/suika/p/9007170.html
Copyright © 2011-2022 走看看