标签:
You are given a tree (an acyclic undirected connected graph) with N nodes, and nodes numbered 1,2,3...,N. Each edge has an integer value assigned to it(note that the value can be negative). Each node has a color, white or black. We define dist(a, b) as the sum of the value of the edges on the path from node a to node b.
All the nodes are white initially.
We will ask you to perfrom some instructions of the following form:
For each "A" operation, write one integer representing its result. If there is no white node in the tree, you should write "They have disappeared.".
Input: 3 1 2 1 1 3 1 7 A C 1 A C 2 A C 3 A Output: 2 2 0 They have disappeared.
大意:
给出一棵树,每个点非白即黑.求树上最远的两个白点之间的距离,中间必须支持动态修改每个点的黑白状态.
思考:
树分治真是个好东西......
边分治有一个非常好的性质:就是一条边能将整棵树分成两个部分.(二分)
所以合并信息是非常方便的.
我们将每个点到中心边的距离求出来并且保存.对于每条中心边,用一个优先队列来保存对应的最优值.
最后我们合并答案即可.
但是边分治的缺点也显而易见.就是菊花树的时候复杂度经常退化.
那么怎么做呢? 我们将这棵树重构,就不会那么退化得厉害了.
代码比较慢,凑合着看....
1 #include<cstdlib> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cctype> 7 #include<ctime> 8 using namespace std; 9 const int maxn = (int)4e5, inf = 0x3f3f3f3f; 10 struct E{ 11 int t,w,last; 12 }e[maxn * 8][3]; 13 int last[maxn * 8][3],edg[3]={1,1,1},ext; 14 void add1(int x,int y,int w){ 15 e[++edg[ext]][ext] = (E){y,w,last[x][ext]}; last[x][ext] = edg[ext]; 16 } 17 void add(int x,int y,int w){ 18 add1(x,y,w); add1(y,x,w); 19 } 20 int getint(){ 21 int ret = 0,t = 1; char ch = getchar(); 22 while(!isdigit(ch)) t = ch == ‘-‘ ? -1 : t, ch = getchar(); 23 while(isdigit(ch)) ret = ret * 10 + ch - ‘0‘, ch = getchar(); 24 return ret * t; 25 } 26 int n,img; 27 int col[maxn * 4]; 28 void rebuild(int x,int fa){ 29 int las = x; 30 for(int i = last[x][0]; i; i = e[i][0].last) 31 if(e[i][0].t != fa){ 32 if(i == last[x][0]) add(x,e[i][0].t,e[i][0].w); 33 else col[++img] = 1, add(las,img,0), add(img,e[i][0].t,e[i][0].w),las = img; 34 } 35 for(int i = last[x][0]; i; i = e[i][0].last) 36 if(e[i][0].t != fa) rebuild(e[i][0].t, x); 37 } 38 struct D{ 39 int x,dis; 40 bool operator <(const D &b) const{ 41 return dis < b.dis; 42 } 43 }; 44 struct SEG{ 45 int ans; 46 int l,r,mid; 47 priority_queue<D>q; 48 void pop(){ 49 while(!q.empty() && col[q.top().x] == 1) q.pop(); 50 } 51 }T[maxn * 4]; 52 int cnt,mid,node,tmax,p; 53 int sz[maxn * 4],vis[maxn * 8]; 54 void pushup(int x){ 55 T[x].ans = -1; 56 T[x].pop(); 57 int l = T[x].l, r = T[x].r; 58 if(l == 0 && r == 0){ 59 if(!T[x].q.empty()) T[x].ans = 0; 60 }else{ 61 if(T[x].ans < T[l].ans) T[x].ans = T[l].ans; 62 if(T[x].ans < T[r].ans) T[x].ans = T[r].ans; 63 if(!T[l].q.empty() && !T[r].q.empty()) 64 T[x].ans = max(T[x].ans, T[l].q.top().dis + T[r].q.top().dis + T[x].mid); 65 } 66 } 67 void getsize(int x,int fa,int dis){ 68 sz[x] = 1; 69 add1(x,p,dis); 70 if(col[x] == 0) T[p].q.push((D){x,dis}); 71 for(int i = last[x][1]; i; i = e[i][1].last) 72 if(e[i][1].t != fa && !vis[i]){ 73 getsize(e[i][1].t, x, dis + e[i][1].w); 74 sz[x] += sz[e[i][1].t]; 75 } 76 } 77 void getmid(int x,int id){ 78 int Max = max(sz[x], node - sz[x]); 79 if(tmax > Max) tmax = Max, mid = id; 80 for(int i = last[x][1]; i; i = e[i][1].last) 81 if(!vis[i] && i != id && i != (id^1)) getmid(e[i][1].t, i); 82 } 83 void work(int tp,int x){ 84 p = tp; 85 getsize(x,0,0); 86 tmax = inf; node = sz[x]; getmid(x,mid = 0); 87 vis[mid] = vis[mid^1] = 1; 88 if(mid){ 89 int l = e[mid][1].t, r = e[mid^1][1].t; 90 T[tp].mid = e[mid][1].w; 91 work(T[tp].l = ++cnt, l); 92 work(T[tp].r = ++cnt, r); 93 } 94 pushup(tp); 95 } 96 void solve(){ 97 int Q = getint(),x; 98 char ch; 99 while(Q--){ 100 scanf("%c\n",&ch); 101 if(ch == ‘A‘){ 102 if(T[1].ans >= 0) printf("%d\n",T[1].ans); 103 else printf("They have disappeared.\n"); 104 } 105 else{ 106 x = getint(); 107 col[x] ^= 1; 108 for(int i = last[x][2]; i; i = e[i][2].last){ 109 if(col[x] == 0)T[e[i][2].t].q.push((D){x,e[i][2].w}); 110 pushup(e[i][2].t); 111 } 112 } 113 } 114 } 115 int main() 116 { 117 freopen("qtree.in","r",stdin); 118 freopen("qtree.out","w",stdout); 119 img = n = getint(); 120 for(int i = 1; i < n; ++i){ 121 int u = getint(), v = getint(), w = getint(); 122 add(u,v,w); 123 } 124 ext = 1; rebuild(1,0); 125 ext = 2; work(cnt = 1, 1); 126 solve(); 127 return 0; 128 }
标签:
原文地址:http://www.cnblogs.com/Mr-ren/p/4207241.html