 What's up guys, my name is Michael Lynn. Welcome to my YouTube channel. Today we're going to go over this next problem for code forces 629 Division 3 tree queries. Okay, we are actually going into some uncharted territory But I hope I could explain it to you guys and pretty much Even though I don't really I couldn't solve this at all. I hope I could explain the editorial to you guys, right? So you're given a root of a tree with n vertices 1n root of the tree is a vertex number 1 a tree is a connected Undirected graph with n minus 1 edges. You're given m queries and then you're given a set of k vertices Your task is to say if there is a path from the root to some vertex u such that each of the given k vertices Either belongs to this path or has a distance 1 to this path Okay, so it's pretty hard to explain what they mean by this problem statement So I'm gonna go repent in paper and show you guys what they mean by this. What do they mean by the problem statement? So we need to print out yes or no If I could start from the root and I traverse downward to a vertex that has a path where all the vertices of My input statement are gonna be in that path either in that path or be one distance away from it So that means so in this case we have three eight nine ten We see here that if I were to start from my root one and go down to ten right through this path One three seven nine ten. I know that three eight and nine is in this path Not three eight nine three nine and ten three nine and ten is in this path Right, so like if I traverse from one to ten one three seven nine ten like if I go down this this path, right? one three seven nine ten and Or that three nine and ten is in this path, right? And eight is one distance away from it from my path that I'm traversing downwards to okay So what this problem statement is saying is that we need to print yes or no if given a node like a given this This query of array values, right? If there is a node where I could traverse all all through all the vertices in this array through that path or It's values one distance away from it Okay, so the reason why eight is one distance away from seven see like eight this this value is one distance away But like we're assuming each depth is value one, right? So we see that eight is one distance away from seven So that's the reason why this array returns. Yes. Okay, like if I were to traverse downward through this path one three seven nine ten we see that three nine and ten is exactly in this path in this path and uh Eight eight is one distance away. So That's basically what the problem statement is asking is that does there exist a Certain path that I could go to traverse downward in it and all the vertices in my array that input that they give me is In that path or it's at least one distance away from that path like eight, okay? so I didn't actually Figure out I couldn't figure out this problem myself So I'll just explain the editorial for you guys. So I'll start there now Okay guys, so I'm gonna start with first things first, okay, so Let's assume that we have the largest depth. Okay, we have the node with the largest depth. So in this case, it's 10 I'm gonna call this FV If I know this is the largest depth then I know that assuming that this This array works right this away this array works. That means that every single vertex before it must either be in the same path of the as this largest depth or It's one distance away from it. Okay. That's why I know so I'm gonna call this Largest depth FV right the reason why we know this is cuz like in this case We saw from our input statement this returns. Yes, right and that's because well ten is the largest depth and from this from this path that we go from one to ten Three eight and nine is in this path of one to ten right this path of one to ten and It's either in this path of one to ten or it's at least one distance away from this path, okay So that's what we know in the beginning now What's next um so Now let's take every single node in our input statement Every single node in our input statement, right? So three eight nine ten except for the largest one so except for FV so We are going to replace three eight nine Three eight and nine with its parent. Okay, so what is its parent? So with three's parent is one So I'm gonna replace three with one eight Eight's parent is seven. So I'm gonna place it with seven nine's parent is Seven so I'm gonna place it with seven and then ten I stay there. Okay so if I replace all the all the other nodes in my In my In my input statement, right my input array with its parent. I know that if The answer is yes If each vertex after the after this replacement belongs to the path from the root to the largest node, right? so in this case all the Every vertex here now at like after I replace it with the parent, right besides last the largest one belongs to the path from one to ten Right to the largest FV see the path from one to ten is one three seven nine ten and all the nodes before here See one seven seven right that these nodes belong to the path from one to ten. Okay, so that's we have to make that clear Okay, so the answer would be yes. If this is true like if it's not then that means that It's not possible, right Okay, so now we just have to need to check if this is true If this statement is true like if the the nodes here All the parent belongs to the largest path so we could do this with a very simple technique We are gonna run depth first search from the root and Calculate every vertex for the first time we visit it with a time Time in and out. Okay time in and out so initially the time is going to start at zero and then we are going to Have a time in and out. Okay, so like a let's say run depth first search from here one And My my my time from one to ten I calculate the time it takes so it starts at zero goes one two three four How many how much time it takes right and I go up to ten? Okay, so I need I know that The time it takes for one to ten is a certain number of in and out. Okay, if I do that for every single vertex I know that if the time in and out is in in the between the boundaries of Whatever I'm checking. I know it's an Ancestor of each other. Okay, that's what I mean So like let's say it for for one to ten Let's say it for the one that the time it takes for one to ten Let's say I have like a time for one ten. It takes like I don't know Five second zero seconds to like five. Okay right then if I were to Take the time of three to nine. Okay This time of three to nine Right is we know it's going to be Between the time it takes from one to ten So if the time of three to nine is like, I don't know two two seconds to four seconds, right? So this is this is going to be the time of three to nine Three to nine and then this is going to be time of one to ten If I know my my intervals for my time T in and then T out is like inside my larger interval of zero My larger in over zero to five. I know it's an ancestor of it Okay, I know that's an ancestor of it So I don't have to calculate this crazy algorithm lowest common ancestor and stuff like that. So Yeah, that's pretty much it so Okay, so how do we check if? whatever node I'm currently at Is in the path from one in the path from the root to the largest node, right to the largest node we can know this is true if the node I'm at which let's say you right if use if the if the root One is a parent of you So let's say I'm checking three. I'm checking three is in this path of one three seven nine ten Well, the root here the root one is a parent of three, right? So it's definitely in this path. Okay of one three seven nine ten and the Root the node I'm at you is the parent of FV okay, so here Three is a very very large grandparent of FV FV the largest depth so that's why three isn't the path from one three seven nine ten. Okay, so yeah, that's how you check it So now let's go to the code and then we'll go over the code together. All right guys So I'm gonna explain their code on how they did theirs. Okay, so I actually just rewrote Most of the variable names to make sure that like it's more readable. So first of all We have to read a number of vertices and then the number of queries. So that's n and m Okay, then because we have a number of vertices. I created you got to create a graph of I did n plus one because like we're indexing at one, right? and then depth indexing n plus one also so we're indexing at one and then we got to create our T in and T out which is like the time in and time out for each vertex, right? And then we put it as n plus one. So Yeah, after that, we're gonna loop from zero to n minus one because that's the number of Vertexes that they said at least in the input statement. That's what they said So then then what would you do is we read in each vertex you and V So like you and V are like two vertexes that are connected So to to add that to our graph. We just push back the each adjacency list At each adjacency list, we're gonna push back U to push back V and then V is gonna have the value, right? V is gonna have the the Adjacency matrix adjacency list at V is gonna have you there also so this would show the neighbors Okay, so use neighbors is gonna have a V V is gonna be one of the use neighbors and then these neighbors is gonna be you okay, so that's gonna Create our graph for us. Okay, then we're gonna set time which is T. T is the time total time We're gonna set that to zero in the beginning, right? Then we're kind of called DFS. So we're gonna run DFS so in DFS We're gonna have a current node the one that we're passing in and The parent and then the depth the current depth, right? So originally the parent is gonna start at negative one and then when we keep calling DFS We're gonna Change this passing the current node right each time. So then we could add We have code to have our This is to tell give us a ray of the parents right and this is the depth the current depth, okay So what do we do? So? Above I also created depths and parents array Vector array right and then what I did was I added the current node into the The current node we gonna add the current depth like the for the depths array We're gonna set the current node to equal to the current depth and the parents node current node equal to its parent Okay, and then we're gonna set our timer at the current node is gonna Set to equal to T and then we add one by T And then this is gonna run DFS. So what does this do? This is gonna go through every single Neighbor it's gonna go through every single neighbor of the current node right current nodes neighbors, right? That's how adjacency matrix is adjacency lists work for graphs If the current node is not equal to parent So like this this prevents you to going through the same loop over and over again in your graph, right? So if my current node of my current neighbor, I'm at is not the parent, right? So then then I could run DFS so I'm gonna run DFS and I'm gonna pass in my current neighbor and then I'm gonna pass in my current node So then now the current node is now the parent and then this would run for for us. So this So if we passing like the parent is as like the Parameter that actually helps a lot because what that does is we don't have to have like a visited array So, yeah, this helps a lot and then I'm gonna add depth plus one Every time I run this so then I don't have to yeah so at depth plus one basically adds one to the depth and Every time you go through a DFS Again, like depth first search again your depth we can increase by one after this DFS We're gonna set our t out at the current node to equal to the time and then we're gonna update the time t plus plus Okay, so after DFS is run Remember we read in the number of queries, right? This is a number of queries So the while m minus minus is gonna read in every single query, right? Okay, so K is the length of the each query Which is the input array remember we said that's the one that we have to check So then what I did was created the input array with the value K and I'm gonna read in every single value for our input array Okay, so now here's the thing what we have to do So remember we have to find the maximum depth node, which is the one that in that 10 The one that we saw into like the 10 in the example case. So what do you have to do? You have to loop through remember our DFS already Set our Depths array right depths array, right? So then now what we do is we're gonna loop through every single node in our input array that they gave us, right? Input array and then what we're gonna do is we're going to get every single depth at every single input array And then we're gonna check if this depth like the current depth is greater than greater than our the Depths at the max depth node, right? So remember you have to get the node that has the maximum depth So yeah, that's what this variable does So then once if it's greater than it then we're gonna set our maximum depth node to equal to the current node Okay, to the current node that we're we want to define. Okay? So once I have the maximum depth node, right the node with the maximum depth which was 10, right? I'm gonna loop through my current Look through my input array again, and if it's not the maximum depth node, right? I'm gonna check if the parent is not the root because if it's not the root then That's good. Then we're gonna have to set each value in our input array to be the parent So remember that one seven seven ten. Yeah, we got to do that We had to set each value in our input array to be its parent. Okay, once we've done that we have to do a We're gonna have to have a boolean. Okay, she's equal to true so once this is done that means that all my Values and my input array is gonna be its parent, right? So now that that's Done then we're gonna have to loop through all input array values again And we have to check if each of our input value is actually an ancestor of the maximum depth node So then remember the maximum depth node is a 10, right? We got to make sure that is All the input values are is a ancestor of the maximum depth node and Yeah, yeah is ancestor so to do that I have to have a function called is ancestor which checks if the input Array the whatever value passing is the ancestor of the maximum depth node and how did we do that on pen and paper? you basically have to return the Make sure the time in and time out is between it so like if the time in and time out for you is like between the bounds of the time in and time out of V like these bounds greater than that means V is an ancestor of you. Okay, that's what it means Yeah, V is an ancestor. I think that's how it works. Yeah, then then after that This is gonna is gonna return a boolean Every single time to check if it's an actual ancestor and then what do we do? We have it our total boolean is equal to true and then we're gonna and it by the return statement So what's that gonna do is that's gonna make sure that every single node in the Node in the input array right is gonna have The ancestor of maximum depth node, right? So yeah after that if it's okay, we're gonna print Yes, otherwise we're gonna print no. So that's the whole code. I hope you guys understood this Yeah Ray com subscribe try coding this yourself and then try coding it yourself again without looking at Their source code or this source code and then see if you could do it if you could do it Then that means that you understand algorithm and yeah Ray com subscribe. I'll check you guys later. Peace