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:\n",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\n",ret);
92         }
93     }
94     return 0;
95 }
View Code

 

posted @ 2015-08-09 16:27  狂徒归来  阅读(206)  评论(0编辑  收藏  举报