zoukankan      html  css  js  c++  java
  • 2015 Multi-University Training Contest 1 hdu 5296 Annoying problem

    Annoying problem

    Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1006    Accepted Submission(s): 330


    Problem Description
    Coco has a tree, whose nodes are conveniently labeled by 1,2,…,n, which has n-1 edge,each edge has a weight. An existing set S is initially empty.
    Now there are two kinds of operation:

    1 x: If the node x is not in the set S, add node x to the set S
    2 x: If the node x is in the set S,delete node x from the set S

    Now there is a annoying problem: In order to select a set of edges from tree after each operation which makes any two nodes in set S connected. What is the minimum of the sum of the selected edges’ weight ?

     
    Input
    one integer number T is described in the first line represents the group number of testcases.( T<=10 ) 
    For each test:
    The first line has 2 integer number n,q(0<n,q<=100000) describe the number of nodes and the number of operations.
    The following n-1 lines each line has 3 integer number u,v,w describe that between node u and node v has an edge weight w.(1<=u,v<=n,1<=w<=100)
    The following q lines each line has 2 integer number x,y describe one operation.(x=1 or 2,1<=y<=n)


     
    Output
    Each testcase outputs a line of "Case #x:" , x starts from 1.
    The next q line represents the answer to each operation.

     
    Sample Input
    1
    6 5
    1 2 2
    1 5 2
    5 6 2
    2 4 2
    2 3 2
    1 5
    1 3
    1 4
    1 2
    2 5
     
    Sample Output
    Case #1:
    0
    6
    8
    8
    4
     
    Author
    FZUACM
     
    Source
     
    解题:LCA居然可以解决这种问题。。。
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 100010;
     4 struct arc {
     5     int to,w,next;
     6     arc(int x = 0,int y = 0,int z = -1) {
     7         to = x;
     8         w = y;
     9         next = z;
    10     }
    11 } e[maxn*20];
    12 int head[maxn],fa[maxn][20],dep[maxn],ti,tot;
    13 int n,q,timeStamp[maxn],node[maxn],dfn[maxn];
    14 void add(int u,int v,int w) {
    15     e[tot] = arc(v,w,head[u]);
    16     head[u] = tot++;
    17 }
    18 void dfs(int u,int f) {
    19     timeStamp[u] = ++ti;
    20     node[ti] = u;
    21     for(int i = head[u]; ~i; i = e[i].next) {
    22         if(e[i].to == f) continue;
    23         dfn[e[i].to] = dfn[u] + e[i].w;
    24         fa[e[i].to][0] = u;
    25         dep[e[i].to] = dep[u] + 1;
    26         for(int j = 1; j < 19; ++j)
    27             fa[e[i].to][j] = fa[fa[e[i].to][j-1]][j-1];
    28         dfs(e[i].to,u);
    29     }
    30 }
    31 int LCA(int u,int v) {
    32     if(dep[u] < dep[v]) swap(u,v);
    33     int log;
    34     for(log = 1; (1<<log) <= dep[u]; ++log);
    35     for(int i = log-1; i >= 0; --i)
    36         if(dep[u] - (1<<i) >= dep[v]) u = fa[u][i];
    37     if(u == v) return u;
    38     for(int i = log-1; i >= 0; --i) {
    39         if(fa[u][i] != fa[v][i]) {
    40             u = fa[u][i];
    41             v = fa[v][i];
    42         }
    43     }
    44     return fa[u][0];
    45 }
    46 set<int>st;
    47 int solve(int u) {
    48     if(st.empty()) return 0;
    49     int x,y;
    50     auto it = st.upper_bound(u);
    51     if(it == st.begin() || it == st.end()) {
    52         x = node[*st.begin()];
    53         y = node[*st.rbegin()];
    54     } else {
    55         x = node[*it];
    56         y = node[*(--it)];
    57     }
    58     u = node[u];
    59     return dfn[u] - dfn[LCA(x,u)] - dfn[LCA(y,u)] + dfn[LCA(x,y)];
    60 }
    61 bool used[maxn];
    62 int main() {
    63     int kase,u,v,w,op,cs = 1;
    64     scanf("%d",&kase);
    65     while(kase--) {
    66         memset(head,-1,sizeof head);
    67         memset(used,false,sizeof used);
    68         scanf("%d%d",&n,&q);
    69         for(int i = ti = tot = 0; i < n-1; ++i) {
    70             scanf("%d%d%d",&u,&v,&w);
    71             add(u,v,w);
    72             add(v,u,w);
    73         }
    74         dep[1] = 1;
    75         int ret = dfn[1] = 0;
    76         dfs(1,-1);
    77         st.clear();
    78         printf("Case #%d:
    ",cs++);
    79         while(q--) {
    80             scanf("%d%d",&op,&u);
    81             u = timeStamp[u];
    82             if(op == 1 && !used[u]) {
    83                 used[u] = true;
    84                 ret += solve(u);
    85                 st.insert(u);
    86             } else if(op == 2 && used[u]) {
    87                 used[u] = false;
    88                 st.erase(u);
    89                 ret -= solve(u);
    90             }
    91             printf("%d
    ",ret);
    92         }
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    CentOS6.7安装部署LNMP(nginx1.8.0+php5.6.10+mysql5.6.12)
    Nginx反向代理
    Nginx+keepalived双机热备(主从模式)
    Nginx+keepalived双机热备(主主模式)
    你若盛开,蝴蝶自来
    expect实现自动分发密钥、网站度量术语
    nfs详解及实现全网备份
    inotify+rsync实现实时同步(附解决crontab中无法执行python脚本的问题)
    斜率优化小结
    UVa1607 poj1435 UVaLive1686 Gates
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4715344.html
Copyright © 2011-2022 走看看