• 3991: [SDOI2015]寻宝游戏


    3991: [SDOI2015]寻宝游戏

    https://www.lydsy.com/JudgeOnline/problem.php?id=3991

    分析:

      虚树+set。

      要求树上许多点之间的路径的总长的2倍。就是虚树。

      结论:如果将所有的点按dfs序拍好,答案就是相邻点之间的路径长度的和*2。所以这个可以按dfn维护一个set,每次操作查找前驱后继。

    代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<cctype>
      7 #include<set>
      8 #include<vector>
      9 #include<queue>
     10 #include<map>
     11 using namespace std;
     12 typedef long long LL;
     13 
     14 inline int read() {
     15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     17 }
     18 
     19 const int INF = 1e9;
     20 const int N = 100005;
     21 
     22 int head[N], nxt[N << 1], to[N << 1], len[N << 1], En;
     23 int deth[N], bel[N], siz[N], son[N], fa[N], id[N], dfn[N], TimeIndex;
     24 LL dis[N];
     25 bool vis[N];
     26 LL tmp, Ans;
     27 set<int> s; 
     28 set<int> :: iterator it;
     29 
     30 void add_edge(int u,int v,int w) {
     31     ++En; to[En] = v; len[En] = w; nxt[En] = head[u]; head[u] = En;
     32     ++En; to[En] = u; len[En] = w; nxt[En] = head[v]; head[v] = En;
     33 }
     34 
     35 void dfs1(int u) {
     36     deth[u] = deth[fa[u]] + 1;
     37     for (int i=head[u]; i; i=nxt[i]) {
     38         int v = to[i];
     39         if (v == fa[u]) continue; 
     40         dis[v] = dis[u] + len[i];
     41         fa[v] = u;
     42         dfs1(v);
     43         siz[u] += siz[v];
     44         if (!son[u] || siz[son[u]] < siz[v]) son[u] = v;
     45     }
     46 }
     47 
     48 void dfs2(int u,int top) {
     49     bel[u] = top;
     50     dfn[u] = ++TimeIndex; id[TimeIndex] = u;
     51     if (!son[u]) return ;
     52     dfs2(son[u], top);
     53     for (int i=head[u]; i; i=nxt[i]) {
     54         int v = to[i];
     55         if (v != fa[u] && v != son[u]) dfs2(v, v);
     56     }
     57 }
     58 
     59 int LCA(int u,int v) {
     60     while (bel[u] != bel[v]) {
     61         if (deth[bel[u]] < deth[bel[v]]) swap(u, v);
     62         u = fa[bel[u]];
     63     }
     64     return deth[u] < deth[v] ? u : v;
     65 }
     66 
     67 LL getdis(int x,int y) {
     68     int lca = LCA(x, y);
     69     return dis[x] + dis[y] - (dis[lca] * 2);
     70 }
     71 
     72 void ins(int x) {
     73     int L = *(--s.lower_bound(dfn[x]));
     74     int R = *(s.upper_bound(dfn[x]));
     75     if (L != -INF) Ans += getdis(id[L], x);
     76     if (R != INF) Ans += getdis(id[R], x);
     77     if (L != -INF && R != INF) Ans -= getdis(id[L], id[R]);
     78     s.insert(dfn[x]); vis[x] = 1;
     79 }
     80 
     81 void del(int x) {
     82     s.erase(dfn[x]); vis[x] = 0;
     83     int L = *(--s.lower_bound(dfn[x]));
     84     int R = *(s.upper_bound(dfn[x]));
     85     if (L != -INF) Ans -= getdis(id[L], x);
     86     if (R != INF) Ans -= getdis(id[R], x);
     87     if (L != -INF && R != INF) Ans += getdis(id[L], id[R]);
     88 }
     89 
     90 int main() {
     91     int n = read(), Q = read();
     92     for (int i=1; i<n; ++i) {
     93         int u = read(), v = read(), w = read();
     94         add_edge(u, v, w);
     95     }
     96     dfs1(1);
     97     dfs2(1, 1);
     98     
     99     s.insert(-INF), s.insert(INF);
    100     
    101     while (Q--) {
    102         tmp = 0;
    103         int x = read();
    104         if (!vis[x]) ins(x);
    105         else del(x);
    106         if (s.size() > 3) {
    107             it = s.begin(); 
    108             int L = *(++it);
    109             it = s.end(); 
    110             int R = *(--(--it));
    111             tmp = getdis(id[L], id[R]);
    112         }
    113         printf("%lld
    ",Ans + tmp);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    腾讯时尚网页精彩专题设计赞赏
    IOS日期转为今天昨天形式
    从12306验证码看人工智能未来发展
    智力题小结(4)
    andriod first app-computer
    java中执行js代码
    Eclipse构建Activiti项目,类导入提示功能不能使用
    在eclipse中安装activiti插件
    windows下多进程加协程并发模式
    python与c#的交互模块pythonnet
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9707262.html
Copyright © 2020-2023  润新知