ZOJ 2314/SGU194 Reactor Cooling

无源汇点上下界可行流问题.....

建图:

对于一条边 u--->v  low(u,v) high(u,v) 连边 u--->v high(u,v) - low(u,v)  就变成了无上下界的网络流问题了

但这样不一定满足low的关系 ,所以我每要再每个点流量后面加上low.....

设自由流g(u,v)=high(u,v) - low(u,v)

每一个点的流量由自由流g和下界流low组成....

变一下型:

可以看到每个点流入流出的流量不一定平衡...

我们用一个数组low记录每个点的下界流量 , 当low[i]<0时流入的下界流小于流出的下界流,也就是

既流出少了 . 我们建一个超级汇点 连一条 i--->T 容量为 -Low[i] 的边.

当Low[i]>0 同理 流入的少了. 建一个超级源点 连一条 S--->i   容量为 Low[i]的边 ... 图就建好了

一个可行流,一定是一个从附加源到附加汇的最大流。而且源点所连的边一定是满流的。

所以跑一遍最大流最后判断一下源点说连的边是否满流,如果满流 说明 存在可行流。没满流,则不存在可行流。

Reactor Cooling


Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge



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:

fi,1+fi,2+...+fi,N = f1,i+f2,i+...+fN,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


Author: Andrew Stankevich

Source: Andrew Stankevich‘s Contest #1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn=100005;
const int INF=0x3f3f3f3f;

struct Edge
{
    int to,next,cap,flow;
}edge[1000000];

int Size,Adj[maxn];
int gap[maxn],dep[maxn],pre[maxn],cur[maxn];

void init()
{
    Size=0;
    memset(Adj,-1,sizeof(Adj));
}

void add_edge(int u,int v,int w,int rw=0)
{
    edge[Size].to=v;edge[Size].cap=w;edge[Size].next=Adj[u];
    edge[Size].flow=0;Adj[u]=Size++;
    edge[Size].to=u;edge[Size].cap=rw;edge[Size].next=Adj[v];
    edge[Size].flow=0;Adj[v]=Size++;
}

int sap(int start,int end,int N)
{
    memset(gap,0,sizeof(gap));
    memset(dep,0,sizeof(dep));
    memcpy(cur,Adj,sizeof(Adj));

    int u=start;
    pre[u]=-1; gap[0]=N;
    int ans=0;

    while(dep[start]<N)
    {
        if(u==end)
        {
            int Min=INF;
            for(int i=pre[u];~i;i=pre[edge[i^1].to])
                if(Min>edge[i].cap-edge[i].flow)
                    Min=edge[i].cap-edge[i].flow;
            for(int i=pre[u];~i;i=pre[edge[i^1].to])
            {
                edge[i].flow+=Min;
                edge[i^1].flow-=Min;
            }
            u=start;
            ans+=Min;
            continue;
        }
        bool flag=false;
        int v;
        for(int i=cur[u];~i;i=edge[i].next)
        {
            v=edge[i].to;
            if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
            {
                flag=true;
                cur[u]=pre[v]=i;
                break;
            }
        }
        if(flag)
        {
            u=v;
            continue;
        }
        int Min=N;
        for(int i=Adj[u];~i;i=edge[i].next)
        {
            if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
            {
                Min=dep[edge[i].to];
                cur[u]=i;
            }
        }
        gap[dep[u]]--;
        if(!gap[dep[u]]) return ans;
        dep[u]=Min+1;
        gap[dep[u]]++;
        if(u!=start) u=edge[pre[u]^1].to;
    }
    return ans;
}

int n,m;
int in[maxn],low[maxn];

int main()
{
    int T_T;
    scanf("%d",&T_T);
    while(T_T--)
    {
        /// INIT
        scanf("%d%d",&n,&m);
        init();
        memset(in,0,sizeof(in));
        memset(low,0,sizeof(low));
        int a,b,c,d;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            in[a]-=c;in[b]+=c;
            low[i]=c;
            add_edge(a,b,d-c);
        }
        for(int i=1;i<=n;i++)
        {
            if(in[i]<0) add_edge(i,n+1,-in[i]);
            if(in[i]>0) add_edge(0,i,in[i]);
        }
        sap(0,n+1,n+2);
        bool flag=true;
        for(int i=Adj[0];~i;i=edge[i].next)
        {
            if(edge[i].cap!=edge[i].flow)
            {
                flag=false; break;
            }
        }
        if(flag==true)
        {
            puts("YES");
            for(int i=0;i<m;i++)
            {
                printf("%d\n",edge[2*i].flow+low[i]);
            }
        }
        else
        {
            puts("NO");
        }
    }
    return 0;
}
时间: 2024-12-26 08:28:05

ZOJ 2314/SGU194 Reactor Cooling的相关文章

SGU194 Reactor Cooling 有下界最大流

学习别人的方法.大致是: 无源汇的最大流 : 新建源点,汇点,sum[i]为每个点进来的下界流之和减去出去的下界流之和,如果sum[i] > 0,由源点向该点建一条边,上界为sum[i],下界为0 如果sum[i] < 0, 由该点向汇点建边,上界为-sum[i],下界为0.跑一遍源点到汇点的最大流即为答案 #include <cstdio> #include <ctime> #include <cstdlib> #include <cstring&g

sgu194 Reactor Cooling【无源汇有上下界可行流】

这是模板题了吧,先建立附加源汇,然后保留每个点的in-out,如果这个值是正的,那么就从附加源先这个点连一个边权为in-out的边,否则从这个点向附加汇连一条相反数的边,剩下题目中的边就用上界-下界连就好了. 1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #def

zoj 2314 Reactor Cooling (无源汇上下界可行流)

Reactor Coolinghttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear re

zoj Reactor Cooling

Reactor Cooling 无源汇上下界最大流问题. 1.流量平衡. 2.满足上下界 模板题. #include <iostream> #include <queue> #include <vector> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 200000 + 10; const int INF = 1 << 30; s

acdream 1211 Reactor Cooling 【边界网络流量 + 输出流量】

称号:acdream 1211 Reactor Cooling 分类:无汇的有上下界网络流. 题意: 给n个点.及m根pipe,每根pipe用来流躺液体的.单向的.每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体.里面流躺物质. 而且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题).同一时候最小不能低于Li. 比如: 46(4个点,6个pipe) 12 1 3 (1->2上界为3,下界为1) 23 1 3

ZOJ2314 Reactor Cooling

Reactor Cooling Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge 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 planni

acdream 1211 Reactor Cooling 【上下界网络流 + 输出流量】

题目:acdream 1211 Reactor Cooling 分类:无源无汇的有上下界网络流. 题意: 给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质. 并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li. 例如: 46(4个点,6个pipe) 12 1 3 (1->2上界为3,下界为1) 23 1 3

zoj2314 Reactor Cooling --- 上下界可行流

题目给出了每条边的上下界, 此类题目的建边方法是: 1.添加源点汇点, 2.对每条边 添加边 c(u,v) = up(u,v) - low(u,v) 3.对每个点 c(s,v) = out(v) c(v,t) = in(v)   (权值为正) 求s到t的最大流,若最大流等于所有边下界的和,则存在可行流, 每条边的流量为 flow(u,v) +low(u,v) #include <iostream> #include <cstring> #include <string>

【SGU 194】 Reactor Cooling

194. Reactor Cooling time limit per test: 0.5 sec. memory limit per test: 65536 KB input: standard output: standard The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear reactor to produce plutonium for t