Codeforces 903G Yet Another Maxflow Problem - 线段树
题目传送门
题目大意
给定一个网络。网络分为$A$,$B$两个部分,每边各有$n$个点。对于$A_{i} \ (1\leqslant i < n)$会向$A_{i + 1}$连一条容量为$x_{i}$的有向边,对于$B_{i} \ (1\leqslant i < n)$会向$B_{i + 1}$连一条容量为$y_{i}$的有向边。$A$和$B$之间有$m$条边,起点为$A_{u_{i}}$,终点为$B_{v_{i}}$,容量为$w_{i}$的有向边。要求支持多次修改边的容量,询问$A_{1}$到$B_{n}$的最大流。
看起来不会退流的样子,所以应该可以用数据结构乱搞搞就能做出来。于是我想了很久但仍然不会。
因为最大流的流量等于最小割的容量,所以最大流不好做的时候考虑最小割。
直接考虑最小割的求解变成了最大流,这样没有用。考虑放宽一下约束条件,找一下怎样的割集是较优的。
一些显而易见的结论:
- 假如在$A$中,割掉$A_{x}$和$A_{x + 1}$之间的有向边,那么割掉$A_{y} \ (y > x)$与$A_{y + 1}$之间的有向边是没有意义的。
- 假如在$B$中,割掉$B_{x}$和$B_{x + 1}$之间的有向边,那么割掉$B_{y} \ (y < x)$与$B_{y + 1}$之间的有向边是没有意义的。
因此,在$A, B$中至多有一条边属于割集。
假设在$A$中被割掉的边是$(A_{x}, A_{x + 1})$,在$B$中被割掉的边是$B_{y}, B_{y + 1}$,那么任意$(A_{u}, B_{v}) \ (u \leqslant x \wedge v > y)$都是属于这个割集的。
因此,割的大小可以看做三部分:在$A$中的割集大小,在$B$中的割集大小,在$A, B$间的割集大小。
由于后两部分不会改变,考虑计算出它们。
考虑在$A$中从小到大枚举$A_{x}$,表示割掉$A_{x}$和$A_{x + 1}$之间的边,如果$x = n$表示不存在这条边。
那么下面要做的事情是在$B$中找到一个最优决策点$y$,使得后两部分的和最小。
对于每加入一条在$A,B$间的边,对答案造成的影响是连续的一段。
所以我们只需要写一个支持区间加,求$[1, n]$的最小值的线段树就好了。
到此,我们完美解决这道题了吗?
不,还剩下合并两部分的答案。这个可以用一个可删堆来维护。
时间复杂度$O((n + m + q)\log n)$。
Code
/**
* Codeforces
* Problem#903G
* Accepted
* Time: 451ms
* Memory: 31200k
*/
#include <bits/stdc++.h>
#ifdef WIN32
#define Auto "%I64d"
#else
#define Auto "%lld"
#endif
using namespace std; #define ll long long typedef class SegTreeNode {
public:
ll minv, lazy;
SegTreeNode *l, *r; SegTreeNode():minv(), lazy(), l(NULL), r(NULL) { } void pushUp() {
minv = min(l->minv, r->minv);
} void pushDown() {
l->minv += lazy, r->minv += lazy;
l->lazy += lazy, r->lazy += lazy;
lazy = ;
}
}SegTreeNode; #define Limit 500000 SegTreeNode pool[Limit];
SegTreeNode* top = pool; SegTreeNode* newnode() {
return top++;
} typedef class SegTree {
public:
SegTreeNode* rt; SegTree() { }
SegTree(int n, int* ar) {
build(rt, , n, ar);
} void build(SegTreeNode*& p, int l, int r, int *ar) {
p = newnode();
if (l == r) {
p->minv = ar[l];
return;
}
int mid = (l + r) >> ;
build(p->l, l, mid, ar);
build(p->r, mid + , r, ar);
p->pushUp();
} void update(SegTreeNode*& p, int l, int r, int ql, int qr, int val) {
if (l == ql && r == qr) {
p->minv += val, p->lazy += val;
return;
}
if (p->lazy) p->pushDown();
int mid = (l + r) >> ;
if (qr <= mid)
update(p->l, l, mid, ql, qr, val);
else if (ql > mid)
update(p->r, mid + , r, ql, qr, val);
else {
update(p->l, l, mid, ql, mid, val);
update(p->r, mid + , r, mid + , qr, val);
}
p->pushUp();
}
}SegTree; #define pii pair<int, int> typedef class Heap {
public:
priority_queue<ll> que;
priority_queue<ll> del; Heap() { } void insert(ll x) {
que.push(-x);
} void remove(ll x) {
del.push(-x);
} ll top() {
while (!que.empty() && !del.empty() && que.top() == del.top())
que.pop(), del.pop();
return -que.top();
}
}Heap; int n, m, q;
int *cs1, *cs2;
vector<pii> *g;
Heap hp;
SegTree st; inline void init() {
scanf("%d%d%d", &n, &m, &q);
cs1 = new int[(n + )];
cs2 = new int[(n + )];
g = new vector<pii>[(n + )];
cs1[n] = , cs2[] = ;
for (int i = ; i < n; i++)
scanf("%d%d", cs1 + i, cs2 + i + );
for (int i = , u, v, w; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(pii(v, w));
}
} ll *olds;
inline void solve() {
olds = new ll[(n + )];
st = SegTree(n, cs2);
for (int i = ; i <= n; i++) {
for (int j = ; j < (signed) g[i].size(); j++)
st.update(st.rt, , n, , g[i][j].first, g[i][j].second);
hp.insert(olds[i] = cs1[i] + st.rt->minv);
// cerr << olds[i] << endl;
}
printf(Auto"\n", hp.top());
int p, nw;
while (q--) {
scanf("%d%d", &p, &nw);
hp.remove(olds[p]);
olds[p] = olds[p] - cs1[p] + nw, cs1[p] = nw;
hp.insert(olds[p]);
printf(Auto"\n", hp.top());
}
} int main() {
init();
solve();
return ;
}
Codeforces 903G Yet Another Maxflow Problem - 线段树的更多相关文章
- 【CF903G】Yet Another Maxflow Problem 线段树
[CF903G]Yet Another Maxflow Problem 题意:一张图分为两部分,左边有n个点A,右边有m个点B,所有Ai->Ai+1有边,所有Bi->Bi+1有边,某些Ai ...
- codeforces 1217E E. Sum Queries? (线段树
codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- [Codeforces 280D]k-Maximum Subsequence Sum(线段树)
[Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...
- Codeforces 1089K - King Kog's Reception - [线段树][2018-2019 ICPC, NEERC, Northern Eurasia Finals Problem K]
题目链接:https://codeforces.com/contest/1089/problem/K time limit per test: 2 seconds memory limit per t ...
- Codeforces 803G Periodic RMQ Problem 线段树
Periodic RMQ Problem 动态开点线段树直接搞, 我把它分成两部分, 一部分是原来树上的, 一部分是后来染上去的,两个部分取最小值. 感觉有点难写.. #include<bits ...
- Codeforces 444 C. DZY Loves Colors (线段树+剪枝)
题目链接:http://codeforces.com/contest/444/problem/C 给定一个长度为n的序列,初始时ai=i,vali=0(1≤i≤n).有两种操作: 将区间[L,R]的值 ...
- Codeforces Gym 100513F F. Ilya Muromets 线段树
F. Ilya Muromets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/probl ...
- Codeforces 834D The Bakery【dp+线段树维护+lazy】
D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...
随机推荐
- 新节点在线加入PXC
环境 192.168.139.151 新增节点 192.168.139.148-150 集群节点 192.168.139.151 已经安装好PXC软件 计划: 选用192.168.139.150 节点 ...
- struts2启动时,出现的com.opensymphony.xwork2.util.finder.ClassFinder - Unable to read class 错误解决办法
在项目的struts.xml文件中第一行加入<constant name="struts.convention.package.locators" value="c ...
- IT新起之秀
辞职以后自己比较迷茫,不知道自己能干什么,09年毕业到现在虽然工作经验有7.8年,但是感觉自己什么都不会,除了自己能下车间别的好像也做不成,没有一技之长.我更像是一个经验用了7.8年而不是有7.8年的 ...
- oauth2.0学习笔记(摘抄简化)
大量摘抄白话简明教程. 附:可以参考<RFC6749协议中文版及oauth2.0>文档 一.OAuth 白话简明教程 1.简述 http://www.cnblogs.com/Ceri/p/ ...
- Unity之如何从fbx提取Animation clip文件
见代码: static void CreateAnim(string fbx, string target) { AnimationClip src = AssetDatabase.LoadAsset ...
- <8>Cocos Creator组件开发cc.Component
1.组件简介 组件是Cocos Creator的主要构成,渲染(场景显示内容).逻辑.用户输入反馈.计时器等等几个方面都是由组件完成的.根据Cocos Creator的总体架构,组件和节点配合完成游戏 ...
- Python全栈-day8-day9-函数1
函数 day8 1.为什么需要函数 1)代码的组织结构不清晰,可读性差 2)需要重复使用某个功能时,需要重新编写成程序,重复率高 3)多处引用相同代码时,需要扩展功能的时候过于麻烦,工作量大 2.函数 ...
- 超简单系列:ubuntu 13.04 安装 apache2.2+mod_wsgi+Django
1,Ubuntu更新系统 sudo apt-get update sudo apt-get upgrade 2,安装apache,mod_wsgi,Django sudo apt-get instal ...
- jquer文字闪烁简单实现
arguments.callee <script type="text/javascript"> (function () { $(".usesend&quo ...
- 20155228 2016-2017-2 《Java程序设计》第3周学习总结
20155228 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 认识对象 类与对象 类和对象的关系:类是对象的设计图,对象是类的实例 参考:将"名 ...