易知,答案就是各个关键点之间形成的树的边权和的两倍,哦。。就是虚树
对于一颗虚树,答案就是各个的dfs序排序,相邻两点的距离和,再加上最后一个到第一个的距离
直接用set维护dfs序就好了
注意最后要剪掉所有关键点的LCA的深度
1 /************************************************************** 2 Problem: 3991 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:7304 ms 7 Memory:42584 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 #include <set> 13 14 using namespace std; 15 const int N = 1e5 + 5; 16 typedef long long ll; 17 typedef set<int> :: iterator iter; 18 19 struct edge { 20 int next, to, v; 21 edge(int _n = 0, int _t = 0, int _v = 0) : next(_n), to(_t), v(_v) {} 22 } e[N << 1]; 23 24 struct tree_node { 25 int fa, w, now; 26 ll dis; 27 } tr[N]; 28 29 int n, m; 30 int first[N], tot; 31 int lg2[N << 1], cnt_seq; 32 ll ans, st[N << 1][20]; 33 set<int> seq; 34 35 inline int read(); 36 37 inline void Add_Edges(int x, int y, int z) { 38 e[++tot] = edge(first[x], y, z), first[x] = tot; 39 e[++tot] = edge(first[y], x, z), first[y] = tot; 40 } 41 42 #define y e[x].to 43 void dfs(int p) { 44 int x; 45 st[tr[p].w = ++cnt_seq][0] = tr[p].dis; 46 for (x = first[p]; x; x = e[x].next) 47 if (y != tr[p].fa) { 48 tr[y].fa = p, tr[y].dis = tr[p].dis + e[x].v; 49 dfs(y); 50 st[++cnt_seq][0] = tr[p].dis; 51 } 52 } 53 #undef y 54 55 ll query(int x, int y) { 56 static int t; 57 t = lg2[y - x + 1]; 58 return min(st[x][t], st[y - (1 << t) + 1][t]); 59 } 60 61 template <class T> inline T nxt(const T &it) { 62 static T tmp; 63 tmp = it; 64 return ++tmp; 65 } 66 67 template <class T> inline T pre(const T &it) { 68 static T tmp; 69 tmp = it; 70 return --tmp; 71 } 72 73 inline void insert(int p) { 74 static iter it; 75 it = seq.insert(p).first; 76 ans += st[p][0]; 77 if (seq.size() == 1) return; 78 if (it == seq.begin()) { 79 ans -= query(*it, *nxt(it)); 80 return; 81 } 82 if (nxt(it) == seq.end()) { 83 ans -= query(*pre(it), *it); 84 return; 85 } 86 ans += query(*pre(it), *nxt(it)) - query(*pre(it), *it) - query(*it, *nxt(it)); 87 } 88 89 inline void erase(int p) { 90 static iter it; 91 it = seq.find(p); 92 ans -= st[p][0]; 93 if (seq.size() == 1) { 94 seq.erase(it); 95 return; 96 } 97 if (it == seq.begin()) { 98 ans += query(*it, *nxt(it)); 99 seq.erase(it); 100 return; 101 } 102 if (nxt(it) == seq.end()) { 103 ans += query(*pre(it), *it); 104 seq.erase(it); 105 return; 106 } 107 ans -= query(*pre(it), *nxt(it)) - query(*pre(it), *it) - query(*it, *nxt(it)); 108 seq.erase(it); 109 } 110 111 ll LCA() { 112 if (seq.size() == 0) return 0ll; 113 return query(*seq.begin(), *pre(seq.end())); 114 } 115 116 int main() { 117 int i, j, x, y, z; 118 n = read(), m = read(); 119 for (i = 1; i < n; ++i) { 120 x = read(), y = read(), z = read(); 121 Add_Edges(x, y, z); 122 } 123 dfs(1); 124 for (lg2[1] = 0, i = 2; i <= cnt_seq; ++i) lg2[i] = lg2[i >> 1] + 1; 125 for (j = 1; j <= lg2[cnt_seq]; ++j) 126 for (i = 1; i + (1 << j) - 1 <= cnt_seq; ++i) 127 st[i][j] = min(st[i][j - 1], st[i + (1 << j - 1)][j - 1]); 128 for (i = 1; i <= m; ++i) { 129 x = read(); 130 if (tr[x].now) tr[x].now = 0, erase(tr[x].w); 131 else tr[x].now = 1, insert(tr[x].w); 132 printf("%lld\n", ans - LCA() << 1); 133 } 134 return 0; 135 } 136 137 inline int read() { 138 static int x, sgn; 139 static char ch; 140 x = 0, sgn = 1, ch = getchar(); 141 while (ch < '0' || '9' < ch) { 142 if (ch == '-') sgn = -1; 143 ch = getchar(); 144 } 145 while ('0' <= ch && ch <= '9') { 146 x = x * 10 + ch - '0'; 147 ch = getchar(); 148 } 149 return sgn * x; 150 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen