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;
struct Edge{
   int from,to,cap,flow;
   Edge(){};
   Edge(int _from,int _to,int _cap,int _flow)
       :from(_from),to(_to),cap(_cap),flow(_flow){};
};

vector<Edge> edges;
vector<int> G[MAXN];
int d[MAXN],cur[MAXN];
int src,sink,N,M;
bool vst[MAXN];

int b[MAXN],du[MAXN];
int sum;

void init(){
   src = N + 1; sink = src + 1;
   for(int i = 0;i <= sink;++i)
      G[i].clear();
   edges.clear();
}

void addEdge(int from,int to,int cap){
   edges.push_back(Edge(from,to,cap,0));
   edges.push_back(Edge(to,from,0,0));
   int sz = edges.size();
   G[from].push_back(sz - 2);
   G[to].push_back(sz - 1);
}

bool BFS(){
    queue<int> Q;
    memset(vst,0,sizeof(vst));
    Q.push(src);
    d[src] = 0;
    vst[src] = 1;

    while(!Q.empty()){
        int x = Q.front(); Q.pop();
        for(int i = 0;i < G[x].size();++i){
            Edge& e = edges[G[x][i]];
            if(!vst[e.to] && e.cap > e.flow){
                vst[e.to] = 1;
                d[e.to] = d[x] + 1;
                Q.push(e.to);
            }
        }
    }

    return vst[sink];
}

int DFS(int x,int a){
   if(x == sink||a == 0)
      return a;

   int flow = 0,f;
   for(int& i = cur[x];i < G[x].size();++i){
       Edge& e = edges[G[x][i]];
       if(d[e.to] == d[x] + 1 && (f = DFS(e.to,min(a,e.cap - e.flow))) > 0){
            e.flow += f;
            edges[G[x][i]^1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0) break;
       }
   }
   return flow;
}

int maxFlow(){
    int flow = 0;
    while(BFS()){
        memset(cur,0,sizeof(cur));
        flow += DFS(src,INF);
    }
    return flow;
}

void solve(){
   int flow = maxFlow();

   if(flow != sum){
      puts("NO");
      return;
   }

   puts("YES");
   for(int i = 0;i < M;++i){
      printf("%d\n",edges[i<<1].flow + b[i]);
   }
}

int main()
{
//    freopen("Input.txt","r",stdin);

    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        init();
        int u,v,c;
        memset(du,0,sizeof(du));
        for(int i = 0;i < M;++i){
            scanf("%d%d%d%d",&u,&v,&b[i],&c);
            addEdge(u,v,c - b[i]);
            du[u] -= b[i];
            du[v] += b[i];
        }
        sum = 0;
        for(int i = 1;i <= N;++i){
            if(du[i] > 0){
                addEdge(src,i,du[i]);
                sum += du[i];
            }
            else
                addEdge(i,sink,-du[i]);
        }

        solve();
    }
    return 0;
}
时间: 2024-08-26 00:37:20

zoj Reactor Cooling的相关文章

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记录每个点的下界流

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

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

SGU 194 Reactor Cooling 带容量上下限制的网络流

建立虚拟的源点和汇点,因为忽略掉了容量下界之后会导致流量不平衡,所以对于每个u,v,u多出来的流量流到汇点,v不够的流量从源点补流 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <ma

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