http://acm.hdu.edu.cn/showproblem.php?pid=5927
题意:给一个树,再给出一个查询(包含不重要点),除了查询给出的不重要点意外的都是重要点。求一个几个中有多少元素,这个集合包括:重要点,不重要点并且是两个不同重要点的共同祖先。
只需要先遍历一遍求出树的深度,父节点,孩子节点个数。
把输入的不重要节点根据深度从深到浅排序,检查每个不重要节点,如果他没有孩子就把他父亲的孩子数减一。如果他有两个以上的孩子,那说明他一定直接或者间接的是两个不同重要节点的祖先。
1 #include<iostream> 2 #include<list> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 struct node 7 { 8 int depth,fa,ch,ch2;//记录层数;父节点是谁;孩子节点的个数;保存孩子节点的个数恢复用(每次查询会修改某些节点的孩子个数) 9 list<int> side;//存边 10 }; 11 node s[100002];//树 12 bool v[100002];//访问标记 13 int s2[100002];//存每次查询的不重要节点 14 void dfs(int n,int de)//dfs求各节点深度,父节点,孩子个数 15 { 16 v[n]=1; 17 s[n].ch=s[n].side.size();//孩子个数等于有关系的点的数量减一(除了根节点) 18 if(n!=1)s[n].ch--; //减一 19 s[n].ch2=s[n].ch;//保存孩子节点个数 20 s[n].depth=de;//深度 21 list<int>::iterator q = s[n].side.begin(); 22 while(q!=s[n].side.end()) 23 { 24 if(v[*q])//由于从根节点开始访问的,父节点肯定已经被访问到了,所以在有关的点中被访问过的就是父节点 25 { 26 s[n].fa = *q; 27 } 28 else 29 { 30 dfs(*q,de+1); 31 } 32 q++; 33 } 34 } 35 36 bool cmp(const int &a,const int &b)//不重要点根据深度排序的比较函数 37 { 38 return s[a].depth>s[b].depth; 39 } 40 41 int main() 42 { 43 int T,t=0; 44 scanf("%d",&T); 45 while(t++<T) 46 { 47 printf("Case #%d:\n", t); 48 int N,n,q,Q,a,b; 49 scanf("%d %d",&N,&Q); 50 n=0; 51 while(n++<N-1) 52 { 53 scanf("%d %d",&a,&b); 54 if(v[a])//多个样例的时候初始化用的 55 { 56 v[a]=0; 57 s[a].side.clear(); 58 } 59 if(v[b]) 60 { 61 s[b].side.clear(); 62 v[b]=0; 63 } 64 s[a].side.insert(s[a].side.begin(),b);//两边都存一下 65 s[b].side.insert(s[b].side.begin(),a); 66 } 67 dfs(1,0); 68 q=0; 69 while(q++<Q) 70 { 71 int x,i=0; 72 scanf("%d",&x); 73 while(i<x) 74 { 75 scanf("%d",&s2[i]); 76 i++; 77 } 78 sort(s2,s2+i,cmp);//根据深度排序从最深的节点开始检查 79 int ans = N - i; 80 i=0; 81 while(i<x) 82 { 83 if(s[s2[i]].ch==0)s[s[s2[i]].fa].ch--;//如果这个不重要节点没有孩子,他父节点的孩子数就减一(他自己不是重要节点,也无法提供是重要节点的子孙,这个子树就没有用了) 84 if(s[s2[i]].ch>=2)ans++;//(如果这个不重要节点的孩子树≥2,那说明他一定是两个不同重要节点的最近祖先) 85 i++; 86 } 87 printf("%d\n",ans); 88 i=0; 89 while(i<x)//把所有不重要节点的父节点的孩子数复原 90 { 91 s[s[s2[i]].fa].ch=s[s[s2[i]].fa].ch2; 92 i++; 93 } 94 } 95 } 96 return 0; 97 }