ZOJ 1314 Reactor Cooling | 上下界无源汇可行流

题意

有一个网络,每条边有流量的上界和下界,求一种方案,让里面的流可以循环往复地流动起来。

题解

上下界无源汇可行流的模型:

  1. 设置虚拟源点和虚拟汇点。
  2. 如果一条边\(u \to v\)的下界是\(mi\)、上界是\(ma\),则在图中建一条\(u \to v\)的边,流量是\(ma - mi\),同时记录\(oud[u] += mi, ind[v] += mi\),分别代表\(u\)实际比图上多流出的流量与\(v\)实际比图上多流入的流量。
  3. 对于每个节点\(u\),如果\(ind[u] > oud[u]\),即这个节点需要额外流入一些流量,则这些让虚拟源点提供这些流量,即连接一条边\(S \to u\),流量为\(ind[u] - oud[u]\);反之,如果\(ind[u] < oud[u]\),即这个节点需要额外流出一些流量,则这些流量流入了虚拟汇点,即连接一条边\(u \to T\),流量为\(oud[u] - ind[u]\)。

然后求一下这个图的最大流,如果\(S\)的所有出边都流满了,则有解,否则无解。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
#define enter putchar('\n')
#define space putchar(' ')
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c > '9' || c < '0')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 205, M = 100005, INF = 0x3f3f3f3f;
int T, n, m, src, des, ans, sum, u[M], v[M], mi[M], ma[M], ind[N], oud[N];
int ecnt = 1, adj[N], cur[N], dis[N], nxt[M], go[M], cap[M];
void init(){
ans = sum = 0;
ecnt = 1;
for(int i = 1; i <= des; i++)
ind[i] = oud[i] = adj[i] = 0;
}
void ADD(int u, int v, int _cap){
go[++ecnt] = v;
nxt[ecnt] = adj[u];
adj[u] = ecnt;
cap[ecnt] = _cap;
}
void add(int u, int v, int _cap){
ADD(u, v, _cap);
ADD(v, u, 0);
}
bool bfs(){
static int que[N], qr;
for(int i = 1; i <= des; i++)
cur[i] = adj[i], dis[i] = -1;
dis[src] = 1, que[qr = 1] = src;
for(int ql = 1; ql <= qr; ql++){
int u = que[ql];
for(int e = adj[u], v; e; e = nxt[e])
if(cap[e] && dis[v = go[e]] == -1){
dis[v] = dis[u] + 1, que[++qr] = v;
if(v == des) return 1;
}
}
return 0;
}
int dfs(int u, int flow){
if(u == des) return flow;
int ret = 0, delta;
for(int &e = cur[u], v; e; e = nxt[e])
if(cap[e] && dis[v = go[e]] == dis[u] + 1){
delta = dfs(v, min(cap[e], flow - ret));
if(delta){
cap[e] -= delta;
cap[e ^ 1] += delta;
ret += delta;
if(ret == flow) break;
}
}
return ret;
}
int main(){
read(T);
while(T--){
read(n), read(m), src = n + 1, des = n + 2;
init();
for(int i = 1; i <= m; i++){
read(u[i]), read(v[i]), read(mi[i]), read(ma[i]);
add(u[i], v[i], ma[i] - mi[i]);
oud[u[i]] += mi[i], ind[v[i]] += mi[i];
}
for(int i = 1; i <= n; i++)
if(ind[i] > oud[i])
add(src, i, ind[i] - oud[i]), sum += ind[i] - oud[i];
else
add(i, des, oud[i] - ind[i]);
while(bfs()) ans += dfs(src, INF);
if(ans < sum)
puts("NO");
else{
puts("YES");
for(int i = 1; i <= m; i++)
write(mi[i] + cap[i * 2 + 1]), enter;
}
}
return 0;
}

ZOJ 1314 Reactor Cooling | 上下界无源汇可行流的更多相关文章

  1. ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)

    题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动. 本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容 ...

  2. ZOJ 2314 Reactor Cooling | 无源汇可行流

    题目: 无源汇可行流例题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题解: 证明什么的就算了,下面给出一种建图方式 ...

  3. hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

    题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...

  4. BZOJ 3876 支线剧情 有源汇有上下界最小费用可行流

    题意: 给定一张拓扑图,每条边有边权,每次只能从第一个点出发沿着拓扑图走一条路径,求遍历所有边所需要的最小边权和 分析: 这道题乍一看,可能会想到什么最小链覆盖之类的,但是仔细一想,会发现不行,一是因 ...

  5. 算法复习——无源汇可行流(zoj2314)

    题目: The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nucl ...

  6. BZOJ 2055 80人环游世界 有上下界最小费用可行流

    题意: 现在有这么一个m人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家.    因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第 ...

  7. zoj 3229 上下界网络最大可行流带输出方案

    收获: 1. 上下界网络流求最大流步骤: 1) 建出无环无汇的网络,并看是否存在可行流 2) 如果存在,那么以原来的源汇跑一次最大流 3) 流量下界加上当前网络每条边的流量就是最大可行流了. 2. 输 ...

  8. POJ2396 Budget(有源汇流量有上下界网络的可行流)

    题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...

  9. ZOJ 2314 无源汇可行流(输出方案)

    Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge The terrorist group leaded by a ...

随机推荐

  1. 大数据入门第二十二天——spark(三)自定义分区、排序与查找

    一.自定义分区 1.概述 默认的是Hash的分区策略,这点和Hadoop是类似的,具体的分区介绍,参见:https://blog.csdn.net/high2011/article/details/6 ...

  2. 大数据入门第十五天——HBase整合:云笔记项目

    一.功能简述 1.笔记本管理(增删改) 2.笔记管理 3.共享笔记查询功能 4.回收站 效果预览: 二.库表设计 1.设计理念 将云笔记信息分别存储在redis和hbase中. redis(缓存):存 ...

  3. go语言之行--golang核武器goroutine调度原理、channel详解

    一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...

  4. 20155237 《JAVA程序设计》实验二(JAVA面向对象程序设计)实验报告

    20155237 <JAVA程序设计>实验二(JAVA面向对象程序设计)实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S ...

  5. Node总结 模块机制

    1. Node中的模块分为两类.一个是node提供的模块,称为核心模块,如http, fs, path:另一类是用户编写的模块,称为文件模块. 2. require()方法接收一个标识符进行模块查找. ...

  6. angular-ui-router速学

    Demo1 初始化 <html ng-app="app"> <head> <style>.active { color: red; font-w ...

  7. stl源码剖析 详细学习笔记 hashset hashmap

    //---------------------------15/03/26---------------------------- //hash_set { /* hash_set概述: 1:这是一个 ...

  8. setBit testBit权限管理

    1.jdk7文档解释 public boolean testBit(int n) Returns true if and only if the designated bit is set. (Com ...

  9. Redis介绍及Jedis基础操作

    1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes ...

  10. Intellij IDEA 2017 debug断点调试技巧与总结详解篇

    转载自csdn----------------------------------------------------------------------https://blog.csdn.net/q ...