zoukankan      html  css  js  c++  java
  • CH#56C(LCA+dfs序)

    题目传送门

    性质是:把节点dfs序以后,异象石按这个序号排序,然后相邻两两求树上距离,这些距离的和除以二就是最小斯坦纳树。

    插入删除的具体操作是根据我们上述性质,用一个set维护dfn,比如插入x,则ans加上:(set里的,即之前已经插进来的)左x + x右 - 左右。

      1 const int maxn = 1e5 + 5;
      2 typedef set<ll> S;
      3 typedef S::iterator Sit;
      4 
      5 int n, m, t, tot, Time;
      6 int head[maxn], to[maxn << 1], nxt[maxn << 1];
      7 int dfn[maxn], mp[maxn];
      8 ll val[maxn << 1], dis[maxn][20];
      9 
     10 int f[maxn][20], d[maxn];
     11 
     12 S s;
     13 ll ans;
     14 
     15 inline void add(int u, int v, ll cost) {
     16     to[++tot] = v, val[tot] = cost, nxt[tot] = head[u], head[u] = tot;
     17 }
     18 
     19 inline void bfs() {
     20     queue<int> Q;
     21     Q.push(1), d[1] = 1;
     22 
     23     while (!Q.empty()) {
     24         int x = Q.front(); Q.pop();
     25 
     26         for (int i = head[x]; i; i = nxt[i]) {
     27             int y = to[i];
     28             if (d[y])    continue;
     29 
     30             d[y] = d[x] + 1;
     31             dis[y][0] = val[i];
     32             f[y][0] = x;
     33 
     34             rep(j, 1, t) {
     35                 f[y][j] = f[f[y][j - 1]][j - 1];
     36                 dis[y][j] = dis[f[y][j - 1]][j - 1] + dis[y][j - 1];
     37             }
     38 
     39             Q.push(y);
     40         }
     41     }
     42 }
     43 
     44 inline void dfs(int cur, int fa) {
     45     dfn[cur] = ++Time;
     46     mp[Time] = cur;
     47 
     48     for (int i = head[cur]; i; i = nxt[i]) {
     49         int v = to[i];
     50         if (v == fa)    continue;
     51         dfs(v, cur);
     52     }
     53 }
     54 
     55 inline Sit getL(Sit it) {
     56     if (it == s.begin())    return --s.end();
     57     return --it;
     58 }
     59 
     60 inline Sit getR(Sit it) {
     61     if (it == --s.end())    return s.begin();
     62     return ++it;
     63 }
     64 
     65 inline ll lca(int x, int y) {
     66     ll ret = 0;
     67 
     68     if (d[x] > d[y])    swap(x, y);
     69 
     70     irep(i, t, 0)
     71         if (d[f[y][i]] >= d[x]) {
     72             ret += dis[y][i];
     73             y = f[y][i];
     74         }
     75 
     76     if (x == y)    return ret;
     77 
     78     irep(i, t, 0)
     79         if (f[x][i] != f[y][i]) {
     80             ret += dis[x][i] + dis[y][i];
     81             x = f[x][i], y = f[y][i];
     82         }
     83 
     84     return ret + dis[x][0] + dis[y][0];
     85 }
     86 
     87 int main() {
     88     read(n);
     89     rep(i, 1, n - 1) {
     90         int u, v;
     91         ll cost;
     92         read(u), read(v), read(cost);
     93         add(u, v, cost), add(v, u, cost);
     94     }
     95 
     96     t = (int)(log(n) / log(2)) + 1;
     97     bfs();
     98     dfs(1, 0);
     99 
    100     read(m);
    101     rep(i, 1, m) {
    102         char str[2];
    103         scanf("%s", str);
    104 
    105         if (str[0] == '?') {
    106             writeln(ans / 2);
    107         } else {
    108             int x;
    109             read(x);
    110 
    111             if (str[0] == '+') {
    112                 if (s.size()) {
    113                     Sit R = s.lower_bound(dfn[x]);
    114                     if (R == s.end())    R = s.begin();
    115                     Sit L = getL(R);
    116 
    117                     ans += lca(mp[*L], x) + lca(x, mp[*R]) - lca(mp[*L], mp[*R]);
    118                 }
    119                 s.insert(dfn[x]);
    120             } else {
    121                 Sit it = s.find(dfn[x]);
    122                 Sit L = getL(it), R = getR(it);
    123 
    124                 ans -= lca(mp[*L], x) + lca(x, mp[*R]) - lca(mp[*L], mp[*R]);
    125                 s.erase(it);
    126             }
    127         }
    128     }
    129 
    130     return 0;
    131 }
  • 相关阅读:
    Android中Handler与Message的简单实例
    折腾蛋疼的Ubuntu1204LTS的U盘安装
    sgs_intro
    把杀某程序封装成sh
    boost 程序库完全开发_ch4_utility
    VS2005 warning C4819处理办法(提示代码页有不兼容的字符)
    Ubuntu1204LTS下xynxyc编译Emacs24.02
    当VS05调试赋值不对时,小心只是IDE的watch在骗你.....
    很好的boost学习资料
    C++实现Creational Singleton模式
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10640194.html
Copyright © 2011-2022 走看看