2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca)

BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among the vertices, m of them are red, while the others are black. The root of the tree is vertex 1 and it’s a red vertex.
Let’s define the cost of a red vertex to be 0, and the cost of a black vertex to be the distance between this vertex and its nearest red ancestor.
Recall that

  • The length of a path on the tree is the sum of the weights of the edges in this path.
  • The distance between two vertices is the length of the shortest path on the tree to go from one vertex to the other.
  • Vertex u is the ancestor of vertex v if it lies on the shortest path between vertex v and the root of the tree (which is vertex 1 in this problem).

As BaoBao is bored, he decides to play q games with the tree. For the i-th game, BaoBao will select ki vertices vi,1, vi,2, . . . , vi,ki on the tree and try to minimize the maximum cost of these ki vertices by changing at most one vertex on the tree to a red vertex.
Note that

  • BaoBao is free to change any vertex among all the n vertices to a red vertex, NOT necessary among the ki vertiecs whose maximum cost he tries to minimize.
  • All the q games are independent. That is to say, the tree BaoBao plays with in each game is always the initial given tree, NOT the tree modi?ed during the last game by changing at most one vertex.

Please help BaoBao calculate the smallest possible maximum cost of the given ki vertices in each game after changing at most one vertex to a red vertex.

输入

There are multiple test cases. The first line of the input is an integer T, indicating the number of test cases. For each test case:
The first line contains three integers n, m and q (2≤m≤n≤105, 1≤q≤2×105), indicating the size of the tree, the number of red vertices and the number of games.
The second line contains m integers r1, r2, . . . , rm (1 = r1 < r2 <...< rm≤n), indicating the red vertices.
The following (n-1) lines each contains three integers ui, vi and wi (1≤ui, vi≤n, 1≤wi≤109),indicating an edge with weight wi connecting vertex ui and vi in the tree.
For the following q lines, the i-th line will first contain an integer ki (1≤ki≤n). Then ki integers vi,1, vi,2, . . . , vi,ki follow (1≤vi,1 < vi,2 < ... < vi,ki≤n), indicating the vertices whose maximum cost BaoBao has to minimize.
It’s guaranteed that the sum of n in all test cases will not exceed 106, and the sum of ki in all test cases will not exceed 2×106.

输出

For each test case output q lines each containing one integer, indicating the smallest possible maximum cost of the ki vertices given in each game after changing at most one vertex in the tree to a red vertex.

样例输入

2
12 2 4
1 9
1 2 1
2 3 4
3 4 3
3 5 2
2 6 2
6 7 1
6 8 2
2 9 5
9 10 2
9 11 3
1 12 10
3 3 7 8
4 4 5 7 8
4 7 8 10 11
3 4 5 12
3 2 3
1 2
1 2 1
1 3 1
1 1
2 1 2
3 1 2 3

样例输出

4
5
3
8
0
0
0

提示

The first sample test case is shown above. Let’s denote C(v) as the cost of vertex v.
For the 1st game, the best choice is to make vertex 2 red, so that C(3) = 4, C(7) = 3 and C(8) = 4. So the answer is 4.
For the 2nd game, the best choice is to make vertex 3 red, so that C(4) = 3, C(5) = 2, C(7) = 4 and C(8) = 5. So the answer is 5.
For the 3rd game, the best choice is to make vertex 6 red, so that C(7) = 1, C(8) = 2, C(10) = 2 and C(11) = 3. So the answer is 3.
For the 4th game, the best choice is to make vertex 12 red, so that C(4) = 8, C(5) = 7 and C(12) = 0.
So the answer is 8.

题意:

给出一棵树,其中某些点是红色,其余点是黑色。定义一个点的花费为这个点到距其最近的红色祖先节点的距离。q次查询,每次查询给出k个节点,允许将最多一个黑色点变为红色, 求这k个点中最大花费的最小值。每次查询相互独立,不影响树的初始结构。

思路:因为要减小指定点的花费,那么很明显,这个变成红色的节点应该在这些节点的所有最近公共祖先中

我们可以二分这些点去寻找,那么二分就应该先找出单调性,先预处理出每个点的花费和其直接到根节点的花费,顺便处理出st表求lca所需要的值

然后二分其花费值,找到最小的满足情况的值

对于二分,我们应该从大到小把节点按照其花费排序,然后检查,如果第一个点,也就是最大的点就<=二分值就可以直接退出(满足情况),否则就遍历节点,求他们的lca(说明要找到一个他们的公共祖先,变成红色,减小花费),直到其花费<=二分值mid。

然后检查之前求出的,把lca变红后,其花费min(原本花费,其到根花费-lca到根花费)是否都满足<=mid,不是就return 0;

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3
  4 const int maxn = 1e5+5;
  5 int T;
  6 int n,m,q;
  7
  8 typedef long long ll;
  9 struct Node
 10 {
 11     int y,next;
 12     int w;
 13 } node[maxn<<1];
 14 int cnt,head[maxn];
 15 bool isRED[maxn];
 16 int subnum[maxn];
 17 void add(int x,int y,int w)
 18 {
 19     node[++cnt].y=y;
 20     node[cnt].w=w;
 21     node[cnt].next=head[x];
 22     head[x]=cnt;
 23 }
 24
 25 ll dis[maxn];
 26 ll DIS[maxn];
 27 int R[maxn];
 28
 29 int d[maxn<<1],tot;
 30 int first[maxn<<1];
 31 int rmq[maxn<<1];
 32
 33 void init()
 34 {
 35     cnt=tot=0;
 36     memset(isRED,0,sizeof(isRED));
 37     memset(head,0,sizeof(head));
 38 }
 39
 40 void dfs(int x,int f,int dep)
 41 {
 42     if(isRED[x])R[x]=x;
 43     else R[x] = R[f];
 44     first[x]=++tot;
 45     rmq[tot]=x;
 46     d[tot] = dep;
 47     DIS[x] = dis[x] - dis[R[x]];
 48     for(int i=head[x]; i; i=node[i].next)
 49     {
 50         int y=node[i].y;
 51         if(y == f)continue;
 52         dis[y]=dis[x]+node[i].w;
 53         dfs(y,x,dep+1);
 54         rmq[++tot]=x;
 55         d[tot]=dep;
 56     }
 57 }
 58
 59 struct ST
 60 {
 61     int m[maxn<<1];
 62     int dp[maxn<<1][20];
 63     void init(int n)
 64     {
 65         m[0]=-1;
 66         for(int i=1; i<=n; i++)
 67         {
 68             m[i] = ((i&(i-1)) == 0)?m[i-1]+1:m[i-1];
 69             dp[i][0]=i;
 70         }
 71         for(int j=1; (1<<j)<=n; j++)
 72         {
 73             for(int i=1; i+(1<<j)-1<=n; i++)
 74             {
 75                 int a = dp[i][j-1];
 76                 int b = dp[i+(1<<(j-1))][j-1];
 77                 dp[i][j] = d[a] < d[b]?a:b;
 78             }
 79         }
 80     }
 81     int RMQ(int l,int r)
 82     {
 83         int k=m[r-l+1];
 84         int a = dp[l][k];
 85         int b = dp[r-(1<<k)+1][k];
 86         if(d[a] < d[b])return rmq[a];
 87         return rmq[b];
 88     }
 89
 90 } ST;
 91 bool cmp(int a,int b)
 92 {
 93     return DIS[a] > DIS[b];
 94 }
 95 bool check(ll mid,int n)
 96 {
 97     if(DIS[subnum[1]] <= mid)return 1;
 98     int lca = subnum[1];
 99     for(int i=2; i<=n; i++)
100     {
101         if(DIS[subnum[i]] <= mid)break;
102         int a = first[lca];
103         int b = first[subnum[i]];
104         if(a > b)swap(a,b);
105         lca = ST.RMQ(a,b);
106     }
107     for(int i=1; i<=n; i++)
108     {
109         if(DIS[subnum[i]] <= mid)return 1;
110         if(dis[subnum[i]] - dis[lca] > mid)return 0;
111     }
112     return 1;
113 }
114 int main()
115 {
116     scanf("%d",&T);
117     while(T--)
118     {
119         scanf("%d%d%d",&m,&n,&q);
120         init();
121         for(int i=1; i<=n; i++)
122         {
123             int tmp;
124             scanf("%d",&tmp);
125             isRED[tmp]=1;
126         }
127         for(int i=1; i<m; i++)
128         {
129             int a,b,c;
130             scanf("%d%d%d",&a,&b,&c);
131             add(a,b,c);
132             add(b,a,c);
133         }
134         dis[1]=0;
135         dfs(1,0,1);
136         ST.init(tot);
137         while(q--)
138         {
139             int N;
140             scanf("%d",&N);
141             for(int i=1; i<=N; i++)scanf("%d",&subnum[i]);
142             sort(subnum+1,subnum+1+N,cmp);
143             ll l=0,r=DIS[subnum[1]];
144             while(l < r)
145             {
146                 ll mid = (l+r)/2;
147                 if(check(mid,N))
148                 {
149                     r=mid;
150                 }
151                 else l=mid+1;
152             }
153             printf("%lld\n",r);
154         }
155     }
156 }

原文地址:https://www.cnblogs.com/iwannabe/p/10897423.html

时间: 2024-08-02 23:43:44

2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca)的相关文章

2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)

BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among the vertices, of them are red, while the others are black. The root of the tree is vertex 1 and it's a red vertex.Let's define the cost of a red verte

2018 ICPC 徐州网络赛

2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution 将环变成链,设\(f[i][0\)~\(2]\),分别表示与第一个数相同,与第一个数不同,与第一个数相同,与第一个数的反相同.然后\(dp\)即可. 时间复杂度:\(O(n)\) B. BE, GE or NE solution 根据题目描述\(dp\)即可. 时间复杂度:\(O(nm)\) C.

2018 ICPC南京网络赛 Set(字典树 + 合并 + lazy更新)

题解:n个集合,你要进行m个操作.总共有3种操作.第一种,合并两个集合x和y.第二张,把特定的集合里面所有的数字加一.第三种,询问在某个集合里面,对于所有数字对2的k次方取模后,有多少个数字等于x. 思路:我们可以对于每一个节点保存一个lazy标记,这个标记类似于线段树中的lazy标记.每次整个集合增加的时候,只改变lazy标记,然后在下一次访问这个节点的时候,再去把这个标记push_down.而这个push_down的方式就是按照之前说的那样,根据lazy的奇偶来判断是否应该交换儿子和额外进位

ICPC 2018 徐州赛区网络赛

ACM-ICPC 2018 徐州赛区网络赛 ?去年博客记录过这场比赛经历:该死的水题 ?一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进. ? ? D. Easy Math 题意: ? 给定 \(n\), \(m\) ,求 \(\sum _{i=1}^{m} \mu(in)\) .其中 $ 1 \le n \le 1e12$ , $ 1 \le m \le 2e9$ ,\(\mu(n)\) 为莫比乌斯函数. ? 思路: ? 容易知道,\(i\) 与 \(n\) 不互质时, \(\m

HDU 5880 Family View (2016 青岛网络赛 C题,AC自动机)

题目链接  2016 青岛网络赛  Problem C 题意  给出一些敏感词,和一篇文章.现在要屏蔽这篇文章中所有出现过的敏感词,屏蔽掉的用$'*'$表示. 建立$AC$自动机,查询的时候沿着$fail$指针往下走,当匹配成功的时候更新$f[i]$ $f[i]$表示要屏蔽以第$i$个字母结尾的长度为$f[i]$的字符串. 原文地址:https://www.cnblogs.com/cxhscst2/p/8452147.html

2019 ICPC 南昌网络赛

2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 // 史上排名最高一次,开场不到两小时队友各A一题加水题共四题,排名瞬间升至三四十名 // 然后后三小时就自闭了,一题都没有突破...最后排名211 hhhh ? ? B. Fire-Fighting Hero 题意 队友做的,待补. ? AC代码 #include<cstdio> #includ

ACM-ICPC 2018 徐州赛区(网络赛)

A. Hard to prepare After Incident, a feast is usually held in Hakurei Shrine. This time Reimu asked Kokoro to deliver a Nogaku show during the feast. To enjoy the show, every audience has to wear a Nogaku mask, and seat around as a circle. There are

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N \times MN×M little squares. That is to say, the h

2018青岛网络赛B

给一颗树,其中树中有一些红色的点,每个点到距离它最近的祖先红点的距离称为它的距离. 每次给一个点子集,可以选择把树中任意一个点变为红色,问怎样让子集里的点的距离最大值最小. 当只有两个点时,肯定是先找到他们的 lca 然后先判断将 lca 染红是否可以让最大的距离变小,如果有一个点的祖先红点在 lca 的子树里那么不管染哪里的点最大的距离最小必定是两个点中的次小值,当有多个点时只需要将点以距离从大到小排序然后依次按这个规则判断即可. 只不过多个点时如果将 lca 染红最大的距离反而比不染变大了,