ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)
题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动。
本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容量网络上各个顶点都满足流量平衡条件,即所有点的∑流入流量=∑流出流量,可以看成里面的流是循环流动的,类似有向图欧拉回路。
而带上下界的网络可行流的求法,是根据网络流中一个流是可行流的充分必要条件——限制条件和平衡条件,去改造原网络,转化成不带下界的容量网络来求解的。数学模型那些证明之类的不难理解,见论文《一种简易的方法求解流量有上下界的网络中网络流问题》。
而改造的方式好像有两种挺流行的,我用的做法是:
- 设d[u]为顶点u出边下界和-入边下界和,新建源点、汇点
- 原网络的弧<u,v>容量设置成其上界-下界
- 对于每一个顶点u,如果d[u]<0则源点向其连容量-d[u]的边,否则其向汇点连容量d[u]的边
- 最后如果和源点相关的弧都满流则存在可行流,而各条边的流量+其在原网络的下界就是一个解
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 222 8 #define MAXM 222*444 9 10 struct Edge{ 11 int v,cap,flow,next; 12 }edge[MAXM]; 13 int vs,vt,NE,NV; 14 int head[MAXN]; 15 16 void addEdge(int u,int v,int cap){ 17 edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0; 18 edge[NE].next=head[u]; head[u]=NE++; 19 edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0; 20 edge[NE].next=head[v]; head[v]=NE++; 21 } 22 23 int level[MAXN]; 24 int gap[MAXN]; 25 void bfs(){ 26 memset(level,-1,sizeof(level)); 27 memset(gap,0,sizeof(gap)); 28 level[vt]=0; 29 gap[level[vt]]++; 30 queue<int> que; 31 que.push(vt); 32 while(!que.empty()){ 33 int u=que.front(); que.pop(); 34 for(int i=head[u]; i!=-1; i=edge[i].next){ 35 int v=edge[i].v; 36 if(level[v]!=-1) continue; 37 level[v]=level[u]+1; 38 gap[level[v]]++; 39 que.push(v); 40 } 41 } 42 } 43 44 int pre[MAXN]; 45 int cur[MAXN]; 46 int ISAP(){ 47 bfs(); 48 memset(pre,-1,sizeof(pre)); 49 memcpy(cur,head,sizeof(head)); 50 int u=pre[vs]=vs,flow=0,aug=INF; 51 gap[0]=NV; 52 while(level[vs]<NV){ 53 bool flag=false; 54 for(int &i=cur[u]; i!=-1; i=edge[i].next){ 55 int v=edge[i].v; 56 if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){ 57 flag=true; 58 pre[v]=u; 59 u=v; 60 //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap)); 61 aug=min(aug,edge[i].cap-edge[i].flow); 62 if(v==vt){ 63 flow+=aug; 64 for(u=pre[v]; v!=vs; v=u,u=pre[u]){ 65 edge[cur[u]].flow+=aug; 66 edge[cur[u]^1].flow-=aug; 67 } 68 //aug=-1; 69 aug=INF; 70 } 71 break; 72 } 73 } 74 if(flag) continue; 75 int minlevel=NV; 76 for(int i=head[u]; i!=-1; i=edge[i].next){ 77 int v=edge[i].v; 78 if(edge[i].cap!=edge[i].flow && level[v]<minlevel){ 79 minlevel=level[v]; 80 cur[u]=i; 81 } 82 } 83 if(--gap[level[u]]==0) break; 84 level[u]=minlevel+1; 85 gap[level[u]]++; 86 u=pre[u]; 87 } 88 return flow; 89 } 90 int low[MAXM],d[MAXN]; 91 int main(){ 92 int t,n,m,a,b,c; 93 scanf("%d",&t); 94 while(t--){ 95 scanf("%d%d",&n,&m); 96 memset(d,0,sizeof(d)); 97 vs=0; vt=n+1; NV=vt+1; NE=0; 98 memset(head,-1,sizeof(head)); 99 for(int i=0; i<m; ++i){ 100 scanf("%d%d%d%d",&a,&b,low+i,&c); 101 addEdge(a,b,c-low[i]); 102 d[a]+=low[i]; 103 d[b]-=low[i]; 104 } 105 int tot=0; 106 for(int i=1; i<=n; ++i){ 107 if(d[i]<0) addEdge(vs,i,-d[i]); 108 else addEdge(i,vt,d[i]),tot+=d[i]; 109 } 110 if(ISAP()!=tot) puts("NO"); 111 else{ 112 puts("YES"); 113 for(int i=0; i<m; ++i){ 114 printf("%d\n",edge[i<<1].flow+low[i]); 115 } 116 } 117 putchar('\n'); 118 } 119 return 0; 120 }
转载于:https://www.cnblogs.com/WABoss/p/5371871.html
ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)相关推荐
- 有源汇上下界最小费用可行流 ---- P4553 80人环游世界(拆点 + 有源汇上下界最小费用可行流)
题目链接 题目大意: 解题思路: 又是一道裸题 . 首先它要求第iii个点只经过ViViVi那么我们就拆点ai,ai+na_i,a_{i+n}ai,ai+n一个点为入点,一个为出点这条边的流量范围 ...
- P4043 [AHOI2014/JSOI2014]支线剧情(有源汇上下界最小费用可行流)
传送门 约束每个点至少要经过一次,因此是上下界网络流. 每经过边都需要相应的边权,且要求耗费边权之和最小,因此是最小费用流. 存在多个终点,需要建立汇点 ttt ,因此是有源汇网络流. 即:有源汇上下 ...
- 有源汇上下界最小费用可行流 ---- P4043 [AHOI2014/JSOI2014]支线剧情(模板)
题目链接 题目大意: 解题思路: 有源汇上下界最小费用可行流模板题目来着 先建出一个有源汇上下界可行流的图,然后注意建图的时候要把每条边的下界的费用提前加到ans里面 然后再对图跑费用流,就是补齐费用 ...
- CCF201812-5 管道清洁【无源汇上下界最小费用可行流】
上下界费用流板子题,不赘述 感觉最重要的一个点 是题目要求回到一号点 我们这样的连边 恰好保证了要求 #include <bits/stdc++.h> using namespace st ...
- bzoj 4108: [Wf2015]Catering|带上下界最小费用可行流
终于搞懂 上下界网络流了! 注意边的数量 #include <cstdio> #include <cstring> #include <iostream> #inc ...
- [BZOJ2502]清理雪道 有上下界网络流(最小流)
2502: 清理雪道 Time Limit: 10 Sec Memory Limit: 128 MB Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有 ...
- hust1342(流量有上下界的最小流)
题意: 给出一个有向无环图(DAG),我们规定有一些边是必须走的,当走到一个出度是0的点时,我们可以瞬移到任何一个我们想去的点,自选起点,走遍所有的必须走的边,使得瞬移次数最少. 思路: 这类题完全没 ...
- [学习笔记]上下界网络流
有的时候,网络流建模要考虑某些边必须选择若干次,又不能多于若干次,而且不太容易转化成比较好的限制模型, 就简单粗暴地给每条边定一个流量的上下界,求在满足上下界的基础上的一些问题. 大概有以下几种. 基 ...
- 有上下界的(费用)网络流全解
有上下界的(费用)网络流 算法思想 无源汇上下界可行流 有源汇上下界最大流 有源汇上下界最小流 有源汇上下界最小费用可行流 训练 LibreOJ #115 LibreOJ #116 LibreOJ # ...
最新文章
- Silverlight OA源代码(Silverlight4+SQLServer2005)
- 在虚拟机上linux系统上上网
- mysql 源码 缓存_MySQL源码:MYSQL存储过程/函数的分析原理及缓存机制
- react 前端解析二进制流_一年半前端跳槽面试经验(头条、微信、shopee)
- python怎么创建字符串_Python 字符串
- 如何允许远程连接到MySQL
- 匿名对象和类名为数据类型(java)
- 拜耳2020年10个新植保制剂商业化,3个生物技术性状项目推进至上市阶段
- 大二 数据结构 期末复习题(仅供参考)
- dell5580bios恢复出厂_如何进入戴尔笔记本bios及恢复bios出厂设置
- 信息学奥赛一本通高手训练1682:最小字典序
- 编程语言【JAVA】编程(4)---摇色子
- android 音频转mp3格式,音频 (六)- 安卓 ndk 将 pcm 转换为 mp3
- Managed Direct3D开发经验浅析
- auto.js朋友圈克隆 截图 上传数据
- SpringBoot集成Minio搭建自己的分布式文件服务器(Minio集成篇)
- jacob为word添加水印
- 机器学习之经典算法(十一) 条件随机场
- kong+konga
- 基于PHP+MySQL的企业人事员工管理系统