HIHO_1041 National Day Outing

Source: Internet
Author: User
Tags bitset

Topics

Given a tree, N nodes, a N-1 edge. Given the M-node, can you find a traversal method that makes the first time to reach the node AI less than the first time to reach AJ (I < J). And each side of the path goes up to two times.

Analysis

my thoughts are:
A depth-first search strategy that, when entering a node A, makes up a collection of all the nodes in a subtree that is the root of that node A, and the points within that collection are joined together in the M-point collection.
Points outside the subtree where Node A is the root cannot be mixed.

     when implemented, defining a global array gblocked[],gblocked[i] means that node I will no longer be accessible (need to be judged and tagged), Gvisited[i] Indicates that node I has been already accessed (&NBSP; the
was passed on the path to the other node before it was accessed). &NBSP;
Traverse m points from beginning to end, for Point Mi:&NBSP;
1) If the node was previously accessed, it fails! &NBSP;
2) Find the path path_new from Mi up to the root and mark the points on the path as visited; &NBSP;
when looking for the path from the node mi to the root node, if the status of one of the intermediate nodes is" unreachable ", it fails! &NBSP;
3) Then, compare the path Mi-1 formed with the previous point Path_old to find the lowest common ancestor node P for Mi and Mi-1. Then In the path from P to Mi-1, the node after P is labeled &NBSP;
is no longer accessible state (gblocked[t] = true). Because it is now out of the subtree of node T. &NBSP;
     after traversing all m nodes, the return succeeds!

refer to the online idea:
1. Pre-processing to determine all nodes that each node can reach. (Recursive by parent node to all nodes that the child node arrives at)
2. From the root node in order to access the M-point, at the access point Mi, if the current point is P, then the child node of p to find the ability to reach Mi
Node Q, then recursively to Q, and Mark Q as "visited", from P cannot find a child node that can access to MI, then backtrack to P's parent node T, from T
Re-recursion

Until all nodes are accessed, or a node in the middle is recursive to the root node still inaccessible

Implement

Solution 1

/* Depth-first search policy, when entering a node A, makes a collection of all the nodes in the subtree that node A is rooted in, and the points within that collection are attached to a block in the M-point collection, and points outside the subtree where Node A is the root cannot be mixed. At the time of implementation, defining the global array gblocked[],gblocked[i] means that node I will no longer be accessible (need to be judged and tagged), gvisited[i] means that node i is currently accessed (passed on the path that previously accessed the other node). Traverse m points from beginning to end, for Point mi:1) if the node was previously accessed, it fails! 2) Find the path path_new from Mi up to the root and mark the points on the path as accessed, and if the status of one of the intermediate nodes is "unreachable" when the path from the node mi to the root node is found, it will fail! 3) Then, compare the path Path_old with the previous point Mi-1 to find the lowest common ancestor node p for Mi and Mi-1. Then, from p to Mi-1, the node after P is marked as "no longer accessible" (gblocked[t] = true), because is now out of the subtree of node T. After traversing all m nodes, the return succeeds! * * #include <iostream> #include <stdio.h> #include <string.h> #include <deque>using namespace STD; #define N 120struct edge{int to;int next; Edge (int t =-1, int n =-1): to (T), next (n) {};}; Edge gedges[n];int gedgeindex;int ghead[n];bool gvisited[n];int gpre[n];int gtravelseq[n];bool gBlocked[N];void Insertedge (int u, int v) {int e = Gedgeindex++;gedges[e].to = V;gedges[e].next = Ghead[u];ghead[u] = E;e = gedgeindex++;ged ges[e].to = U;gedges[e].next = Ghead[v];ghead[v] = e;} DFS determines the structure of the tree, because the point pair that is given at the beginning is not necessarily the parent-child, so you need to traverse the diagramTo determine the tree's parent-child relationship void Dfs (int u) {gvisited[u] = true;for (int e = Ghead[u]; e = =-1; e = gedges[e].next) {int v = gedges[e].to;if (!gvisited[v]) {Gpre[v] = U;dfs (v);}}} Look for path from node u up to root node bool path (int u, deque<int>& path) {path.clear (); while (U! =-1) {if (Gblocked[u]) {return false;} Gvisited[u] = true;path.push_back (u); u = Gpre[u];} return true;} Determines whether the M nodes can be traversed sequentially, N is the number of nodes bool Cantravel (int m, int n) {if (M <= 0) return false;if (Gtravelseq[0] > N) return false;m Emset (gvisited, False, sizeof (gvisited));d eque<int> Last_path; Save path BOOL Can_path = Path (gtravelseq[0], Last_path);d eque<int> path;for (int i = 1; i < m; i++) {int u = gtravels Eq[i];if (U > N | | gvisited[u])//node U is accessed during the node prior to access, returning failure return False;can_path = Path (gtravelseq[i], path); if (!can_pa TH)//To find the path from node u to the root node, encountered "No longer access" node, return failure returns false; int k1 = last_path.size ()-1;int K2 = path.size ()-1;//Find the nearest public ancestor while (K1 >= 0 && K2 >= 0 && last_p ATH[K1] = = Path[k2]) {--k1;--k2;} if (K1 >= 0)///Nearest public ancestor to Gtravelseq[i-1] next point, marked as no more access gblocked[last_path[k1]] = True;last_path = path;} return true;} void Init () {memset (gvisited, False, sizeof (gvisited)); memset (Gpre,-1, sizeof (GPRE)); memset (Gedges,-1, sizeof (gedges ); memset (Ghead,-1, sizeof (Ghead)), memset (gblocked, False, sizeof (gblocked)); gedgeindex = 0;} int main2 () {int T, n, M, U, v;scanf ("%d", &t), while (t--) {Init (); scanf ("%d", &n); for (int i = 0; i < n-1; i++ {scanf ("%d%d", &u, &v); Insertedge (U, v);} DFS (1); scanf ("%d", &m), for (int i = 0; i < m; i++) {scanf ("%d", & (Gtravelseq[i]));} BOOL ret = Cantravel (M, N), if (ret) printf ("yes\n"); elseprintf ("no\n");} return 0;}

  Solution 2

/* Reference Online Practices: 1. Preprocessing to determine all nodes that each node can reach. (Recursive for all nodes that can reach the child node through the parent node) 2. From the root node in order to access the M-point, at the access point Mi, if the current point is P, then the child node of p to find the node Q can reach Mi, and then recursive to Q, and Mark Q as "visited", From P cannot find a child node that can access to MI, it goes back to the parent node of P, from t to recursion until all nodes are accessed, or the middle node is recursive to the root node still inaccessible */#include <iostream> #include <stdio.h > #include <string.h> #include <deque> #include <bitset>using namespace std; #define N 120struct Edge {int to;int next; Edge (int t =-1, int n =-1): to (T), next (n) {};}; Edge gedges[n];int gedgeindex;int ghead[n];bool gvisited[n];int gpre[n];int gtravelseq[n];bitset<n> GCanReach[N ]; Determine if the node can reach other nodes, with Bitset can conveniently do bit operation void Insertedge (int u, int v) {int e = Gedgeindex++;gedges[e].to = V;gedges[e].next = GH Ead[u];ghead[u] = E;e = gedgeindex++;gedges[e].to = U;gedges[e].next = Ghead[v];ghead[v] = e;} Determine all nodes that can be reached from u void Canreach (int u) {gcanreach[u][u] = 1;gvisited[u] = true;for (int e = Ghead[u]; E! =-1; e = GEDGES[E].N EXT) {int v = gedges[e].to;if (!gvisited[v]) {//If true, the parent node of V is u gpre[v] = u; Canreach (v); Gcanreach[u] |= GCANREACH[V];}}}  The current node is U, the index that needs to be traversed sequentially, M is the number of nodes that need access bool Cantravel (int u, int index, int m) {if (index = = m)//all nodes have visited return true;if (U = =-1)//finally cannot continue to access the return false;gvisited[u] = true;if (U = = Gtravelseq[index]) {//access to a node, starting from the current node to continue the next return Cantravel (U, index + 1, m);} for (int e = Ghead[u]; e = =-1; e = gedges[e].next) {int v = gedges[e].to;//looks up from the child nodes of the current node and can reach the target node if (!gvisited[v] && Gcanreach[v][gtravelseq[index]] {return cantravel (V, index, M);}} Back to the previous node return Cantravel (Gpre[u], index, m);} void Init () {memset (gvisited, False, sizeof (gvisited)); memset (Gedges,-1, sizeof (gedges)); memset (Ghead,-1, sizeof ( Ghead)); memset (Gpre,-1, sizeof (GPRE)); for (int i = 0; i < N; i++) {gcanreach[i].reset (0);} Gedgeindex = 0;} int main () {int T, n, M, U, v;scanf ("%d", &t), while (t--) {Init (); scanf ("%d", &n); for (int i = 0; i < n-1; i++) {scanf ("%d%d", &u, &v); Insertedge (U, v);} Canreach (1); scanf ("%d", &m), for (int i = 0; i < m; i++) {scanf ("%d", & (Gtravelseq[i]));} Memset (gvisited, False, sizeof (gvisited)), BOOL ret = cantravel (1, 0, M), if (ret) printf ("yes\n"); elseprintf ("no\n");} return 0;}

HIHO_1041 National Day Outing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.