标签:
堆:堆最重要的性质就是儿子的值一定不小于父亲的值。除此之外,树的节点是按从上到下、从左到右的顺序紧凑排列的。
本题的堆是一种叫做二叉堆的数据结构。
《挑战程序设计》 P71
对于这题,首先要模拟出二叉树的结构,根据题意通过value[]保存每个节点的权值(值)
再将每两节点之间是否有边连接,保存为tree[][],通过输入的两节点a,b,即保存tree[a][b] = 1
1. 在接下来的深搜中,只需搜索tree[][] == 1的节点
2. 同时,在搜索中还需要满足最小堆(堆)的性质,即value[节点] <= value[子节点]
若符合以上1.2两个条件,则继续向深处(子节点)搜索
即dfs(深度优先搜索)的性质:列举出所有可能,每种可能搜索至,直到边界,或不符合条件为止。(不撞南墙不回头)
依旧,还需要一个数组来保存,当前的节点是否被搜索过,即see[] = 1
1 #include<iostream> 2 #include<cstring> 3 #define Max(a,b) (a > b ? a : b) 4 #define Min(a,b) (a < b ? a : b) 5 const int MAXN = 410; 6 int value[MAXN],tree[MAXN][MAXN],see[MAXN],ac,m; 7 void dfs(int k){ 8 see[k] = 1; //表示已搜过 9 for(int j = 1;j <= m;j++){ 10 if(tree[k][j] && !see[j]){ //没搜索过,并且两节点间存在边 11 if(value[k] <= value[j]) //当前节点权值小于或等于它的子节点权值 12 dfs(j); 13 else 14 ac = 1; 15 } 16 } 17 } 18 int main(){ 19 int n; 20 scanf("%d",&n); 21 while(n--){ 22 memset(tree,0,sizeof(tree)); 23 memset(see,0,sizeof(see)); 24 int i; 25 scanf("%d",&m); 26 for(i = 1;i <= m;i++){ 27 scanf("%d",&value[i]); 28 } 29 for(i = 1;i < m;i++){ 30 int a,b; 31 scanf("%d%d",&a,&b); 32 tree[a][b] = 1; 33 } 34 ac = 0; 35 dfs(1);//从根节点开始 36 printf(ac ? "No\n" : "Yes\n") ; 37 } 38 return 0; 39 }
标签:
原文地址:http://www.cnblogs.com/zhengbin/p/4488830.html