BZOJ - 3218 A+B Problem

bzoj

uoj

首先如果我们不考虑奇怪的点的话,这道题就是一个很显然的最小割了。

建图也很显然:$<s,i,w_i> \; <i,t,b_i> \; ANS = \sum_i{b_i+w_i}-\mbox{maxflow}$

加入奇怪的点:$<i',i,p_i> \; <j, i', \infty>$其中$j<i \wedge l_i \leqslant a_j \lesqslant r_i$

但是这样直接建图的话边数会爆炸,所以我们用线段树优化建图。由于$j<i$这个限制,要用到可持久化线段树。

写给自己:网络流ecnt=1!!!

  1 #include<bits/stdc++.h>
  2 const int INF = 1e9;
  3 using namespace std;
  4 #define nc getchar
  5 inline void read(int &x) {
  6     char b = nc(); x = 0;
  7     for (; !isdigit(b); b = nc());
  8     for (; isdigit(b); b = nc()) x = x * 10 + b - '0';
  9 }
 10 const int N = 5005, M = 150005;
 11 struct Edge {
 12     int v, c, n;
 13 } E[1500000];
 14 int ecnt = 1, d[M], cur[M], _s, _t, head[M];
 15 int tot;
 16 inline void aE(int u, int v, int c) {
 17     E[++ecnt] = (Edge){v, c, head[u]}; head[u] = ecnt;
 18 }
 19 inline void ae(int u, int v, int c) {
 20     if (u == 0 || v == 0) return ;
 21     aE(u, v, c); aE(v, u, 0);    
 22 }
 23 bool bfs() {
 24     for (int i = 1; i <= tot; ++i) d[i] = 0;
 25     d[_s] = 1; queue < int > q; q.push(_s);
 26     while (!q.empty()) {
 27         int u = q.front(); q.pop();
 28         for(int i = head[u]; i; i = E[i].n) {
 29             if (!d[E[i].v] && E[i].c > 0) {
 30                 d[E[i].v] = d[u] + 1;
 31                 q.push(E[i].v);
 32                 if (E[i].v == _t) return true;
 33             }    
 34         }
 35     }
 36     return false;
 37 }
 38 int dfs(int u, int a) {
 39     if (u == _t || a == 0) return a;
 40     int flow = 0, f;
 41     for (int &i = cur[u]; i; i = E[i].n) {
 42         if (d[E[i].v] == d[u] + 1 && (f = dfs(E[i].v, min(a, E[i].c))) > 0) {
 43             flow += f;
 44             E[i].c -= f;
 45             E[i^1].c += f;
 46             a -= f;
 47             if (!a) break;
 48         }
 49     }
 50     return flow;
 51 }
 52 int dinic() {
 53     int flow = 0;
 54     while (bfs()) {
 55         for (int i = 1; i <= tot; ++i)
 56             cur[i] = head[i];
 57         flow += dfs(_s, INF);
 58     }
 59     return flow;
 60 }
 61 int n, a[N], b[N], w[N], l[N], r[N], p[N], v[N*3], H;
 62 inline int idx(int x) {
 63     return lower_bound(v + 1, v + 1 + H, x) - v;
 64 }
 65 struct Node {
 66     Node *ch[2]; int id;    
 67 } mem[N*16], *rt[N], *C = mem, Tnull, *null = &Tnull;
 68 inline Node* newNode(int v, Node *p) {
 69     C->ch[0] = p->ch[0]; C->ch[1] = p->ch[1];
 70     C->id = v; return C++;
 71 }
 72 #define lson l, m, t->ch[0]
 73 #define rson m + 1, r, t->ch[1]
 74 void insert(Node *&p, int x, int po, int l, int r, Node *&t) {
 75     t = newNode(++tot, p);
 76     if (l == r)    return ae(x, t->id, INF), ae(p->id, t->id, INF);
 77     int m = (l + r) >> 1;
 78     if (po <= m) {
 79         insert(p->ch[0], x, po, lson);
 80     } else {
 81         insert(p->ch[1], x, po, rson);
 82     }
 83     ae(t->ch[0]->id, t->id, INF);
 84     ae(t->ch[1]->id, t->id, INF);
 85 }
 86 void link(int x, int L, int R, int l, int r, Node *&t) {
 87     if (t == null) return;
 88     if (L <= l && r <= R)
 89         return ae(t->id, x, INF);    
 90     int m = (l + r) >> 1;
 91     if (L <= m) link(x, L, R, lson);
 92     if (m < R) link(x, L, R, rson);
 93 }
 94 int main() {
 95     null->ch[0] = null->ch[1] = null;
 96     read(n); int ans = 0;
 97     for (int i = 0; i <= n; ++i) rt[i] = null;
 98     _s = n + n + 1, _t = _s + 1; tot = _t;
 99     for (int i = 1; i <= n; ++i) {
100         read(a[i]); read(b[i]); read(w[i]);
101         read(l[i]); read(r[i]); read(p[i]);
102         v[++H] = a[i]; v[++H] = l[i]; v[++H] = r[i];    
103         ans += w[i] + b[i];
104         if (l[i] > r[i]) swap(l[i], r[i]);
105     }
106     sort(v + 1, v + 1 + H);
107     H = unique(v + 1, v + 1 + H) - v - 1;
108     for (int i = 1; i <= n; ++i) {
109         a[i] = idx(a[i]); l[i] = idx(l[i]); r[i] = idx(r[i]);
110         ae(_s, i, w[i]); ae(i, _t, b[i]); ae(i + n, i, p[i]);
111     }
112     for (int i = 1; i <= n; ++i) {
113         link(i + n, l[i], r[i], 1, H, rt[i-1]);
114         insert(rt[i-1], i, a[i], 1, H, rt[i]);
115     }
116     printf("%d\n", ans - dinic());
117     return 0;
118 }

 

posted @ 2018-03-11 15:04  p0ny  阅读(131)  评论(0编辑  收藏  举报