zoukankan      html  css  js  c++  java
  • Codeforces 903G Yet Another Maxflow Problem

    题目传送门

      传送门I

      传送门II

      传送门III

    题目大意

      给定一个网络。网络分为$A$,$B$两个部分,每边各有$n$个点。对于$A_{i} (1leqslant i < n)$会向$A_{i + 1}$连一条容量为$x_{i}$的有向边,对于$B_{i} (1leqslant 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

      1 /**
      2  * Codeforces
      3  * Problem#903G
      4  * Accepted
      5  * Time: 451ms
      6  * Memory: 31200k
      7  */
      8 #include <bits/stdc++.h>
      9 #ifdef WIN32
     10 #define Auto "%I64d"
     11 #else
     12 #define Auto "%lld"
     13 #endif
     14 using namespace std;
     15 
     16 #define ll long long
     17 
     18 typedef class SegTreeNode {
     19     public:
     20         ll minv, lazy;
     21         SegTreeNode *l, *r;
     22 
     23         SegTreeNode():minv(0), lazy(0), l(NULL), r(NULL)    {    }
     24 
     25         void pushUp() {
     26             minv = min(l->minv, r->minv);
     27         }
     28 
     29         void pushDown() {
     30             l->minv += lazy, r->minv += lazy;
     31             l->lazy += lazy, r->lazy += lazy;
     32             lazy = 0;
     33         }
     34 }SegTreeNode;
     35 
     36 #define Limit 500000
     37 
     38 SegTreeNode pool[Limit];
     39 SegTreeNode* top = pool;
     40 
     41 SegTreeNode* newnode() {
     42     return top++;
     43 }
     44 
     45 typedef class SegTree {
     46     public:
     47         SegTreeNode* rt;
     48 
     49         SegTree() {    }
     50         SegTree(int n, int* ar) {
     51             build(rt, 1, n, ar);
     52         }
     53 
     54         void build(SegTreeNode*& p, int l, int r, int *ar) {
     55             p = newnode();
     56             if (l == r) {
     57                 p->minv = ar[l];
     58                 return;
     59             }
     60             int mid = (l + r) >> 1;
     61             build(p->l, l, mid, ar);
     62             build(p->r, mid + 1, r, ar);
     63             p->pushUp();
     64         }
     65 
     66         void update(SegTreeNode*& p, int l, int r, int ql, int qr, int val) {
     67             if (l == ql && r == qr) {
     68                 p->minv += val, p->lazy += val;
     69                 return;
     70             }
     71             if (p->lazy)    p->pushDown();
     72             int mid = (l + r) >> 1;
     73             if (qr <= mid)
     74                 update(p->l, l, mid, ql, qr, val);
     75             else if (ql > mid)
     76                 update(p->r, mid + 1, r, ql, qr, val);
     77             else {
     78                 update(p->l, l, mid, ql, mid, val);
     79                 update(p->r, mid + 1, r, mid + 1, qr, val);
     80             }
     81             p->pushUp();
     82         }
     83 }SegTree;
     84 
     85 #define pii pair<int, int>
     86 
     87 typedef class Heap {
     88     public:
     89         priority_queue<ll> que;
     90         priority_queue<ll> del;
     91 
     92         Heap()    {    }
     93 
     94         void insert(ll x) {
     95             que.push(-x);
     96         }
     97 
     98         void remove(ll x) {
     99             del.push(-x);
    100         }
    101 
    102         ll top() {
    103             while (!que.empty() && !del.empty() && que.top() == del.top())
    104                 que.pop(), del.pop();
    105             return -que.top();
    106         }
    107 }Heap;
    108 
    109 int n, m, q;
    110 int *cs1, *cs2;
    111 vector<pii> *g;
    112 Heap hp;
    113 SegTree st;
    114 
    115 inline void init() {
    116     scanf("%d%d%d", &n, &m, &q);
    117     cs1 = new int[(n + 1)];
    118     cs2 = new int[(n + 1)];
    119     g = new vector<pii>[(n + 1)];
    120     cs1[n] = 0, cs2[1] = 0;
    121     for (int i = 1; i < n; i++)
    122         scanf("%d%d", cs1 + i, cs2 + i + 1);
    123     for (int i = 1, u, v, w; i <= m; i++) {
    124         scanf("%d%d%d", &u, &v, &w);
    125         g[u].push_back(pii(v, w));
    126     }
    127 }
    128 
    129 ll *olds;
    130 inline void solve() {
    131     olds = new ll[(n + 1)];
    132     st = SegTree(n, cs2);
    133     for (int i = 1; i <= n; i++) {
    134         for (int j = 0; j < (signed) g[i].size(); j++)
    135             st.update(st.rt, 1, n, 1, g[i][j].first, g[i][j].second);
    136         hp.insert(olds[i] = cs1[i] + st.rt->minv);
    137 //        cerr << olds[i] << endl;
    138     }
    139     printf(Auto"
    ", hp.top());
    140     int p, nw;
    141     while (q--) {
    142         scanf("%d%d", &p, &nw);
    143         hp.remove(olds[p]);
    144         olds[p] = olds[p] - cs1[p] + nw, cs1[p] = nw;
    145         hp.insert(olds[p]);
    146         printf(Auto"
    ", hp.top());
    147     }
    148 }
    149 
    150 int main() {
    151     init();
    152     solve();
    153     return 0;
    154 }
  • 相关阅读:
    性能测试知多少吞吐量
    性能测试知多少性能测试工具原理与架构
    性能测试知多少了解前端性能
    性能测试知多少响应时间
    性能测试知多少性能测试流程
    LoadRunner脚本编写之三(事务函数)
    测试人员的家在哪儿
    oracle的启动过程
    Oracle表空间(tablespaces)
    LoadRunner脚本编写之二
  • 原文地址:https://www.cnblogs.com/yyf0309/p/8724558.html
Copyright © 2011-2022 走看看