Paths on the tree
Time Limit: 4000/2000 MS (Java/others) memory limit: 131072/131072 K (Java/Others)
Total submission (s): 531 accepted submission (s): 182
Problem descriptionbobo has a tree, whose vertices are conveniently labeled by 1, 2 ,..., N.
There are m paths on the tree. Bobo wowould like to pick some paths while any two paths do not share common vertices.
Find the maximum number of paths Bobo can pick.
Inputthe input consists of several tests. For each tests:
The first line contains n, m (1 ≤ n, m ≤105 ). each of the following (n-1) lines contain 2 integers AI, Bi denoting an edge between vertices AI and Bi (1 ≤ AI, Bi ≤ n ). each of the following M lines contain 2 integers UI, VI denoting a path between vertices UI and VI (1 ≤ UI, VI ≤ n ).
Outputfor each tests:
A single integer, the maximum number of paths.
Sample input3 21 31 21 21 37 31 21 32 42 53 63 72 34 56 7
Sample output12
Question meaning:
Give a tree with n-1 edges. Then give the numbers of the nodes at both ends of M paths, and find the maximum number of nodes with M paths not intersecting.
Ideas:
Find the closest public node of the endpoints at both ends of each path, and sort the LCA values from large to small, and then greedy. If the vertices on this path are not visited each time, then ans ++, and then all the vertices in this path are visited. The final result is ans.
Code:
1 # include <cstdio> 2 # include <cstring> 3 # include <algorithm> 4 # include <vector> 5 # include <queue> 6 # include <iostream> 7 using namespace std; 8 # define n 100005 9 # define M 20 10 11 int n, m; 12 13 struct edge {14 int U, V, F, W; 15 edge (int A = 0, int B = 0, int C = 0, int D = 0): U (A), V (B), F (C), w (d) {} 16} e [N]; 17 18 int Dep [N]; 19 int f [N] [m]; 20 int visited [N]; 21 vector <int> ve [N]; 22 23 void Init (){ 24 memset (DEP, 0, sizeof (DEP); 25 memset (F, 0, sizeof (f); 26 memset (visited, 0, sizeof (visited )); 27 For (INT I = 0; I <= N; I ++) ve [I]. clear (); 28} 29 30 bool CMP (edge a, edge B) {// sort the path from large to small according to the depth of the recent common ancestor 31 return. w> B. w; 32} 33 void BFS (int ss) {// BFS evaluate the depth Dep [] and the number of steps going up f [] [] (online algorithm) 34 queue <int> q; 35 Dep [ss] = 1; 36 f [ss] [0] = 1; 37 Q. push (SS); 38 int U, V, I; 39 while (! Q. empty () {40 u = Q. front (); 41 Q. pop (); 42 for (I = 1; I <m; I ++) f [u] [I] = f [f [u] [I-1] [I-1]; 43 for (I = 0; I <ve [u]. size (); I ++) {44 V = ve [u] [I]; 45 if (V! = F [u] [0]) {46 Dep [v] = Dep [u] + 1; 47 F [v] [0] = u; 48 Q. push (V); 49} 50} 51} 52} 53 54 void DFS (int u) {// DFS visited all the points below the recent common ancestor node so that this path is all visited 55 int V, I; 56 visited [u] = 1; 57 for (I = 0; I <ve [u]. size (); I ++) {58 V = ve [u] [I]; 59 If (DEP [v]> Dep [u] &! Visited [v]) {60 DFS (V); 61} 62} 63} 64 65 int LCA (int x, int y) {// obtain the recent common ancestor 66 If (DEP [x] <Dep [y]) Swap (x, y) of X and Y; 67 int I, K; 68 K = Dep [x]-dep [y]; 69 for (I = 0; I <m; I ++) {70 if (1 <I & K) X = F [x] [I]; 71} 72 If (x = y) return X; 73 for (I = M-1; I> = 0; I --) {74 if (F [x] [I]! = F [y] [I]) {75 x = f [x] [I]; 76 y = f [y] [I]; 77} 78} 79 return f [x] [0]; 80} 81 82 main () 83 {84 int X, Y; 85 int I, J, K, ans; 86 while (scanf ("% d", & N, & M) = 2) {87 Init (); 88 for (I = 1; I <N; I ++) {89 scanf ("% d", & X, & Y); 90 ve [X]. push_back (y); 91 ve [Y]. push_back (x); 92} 93 BFS (1); 94 for (I = 0; I <m; I ++) {95 scanf ("% d ", & X, & Y); 96 int FF = LCA (x, y); 97 // printf ("% d \ n", ff ); 98 E [I] = edge (X, Y, FF, DEP [ff]); 9 9} 100 sort (E, E + M, CMP); 101 ans = 0; 102 for (I = 0; I <m; I ++) {103 If (! Visited [E [I]. u] &! Visited [E [I]. v]) {// if the two endpoints are not visited, the entire path is not visited. Think about why 104 DFS (E [I]. f); 105 ans ++; 106} 107} 108 printf ("% d \ n", ANS); 109} 110}