pat1053. Path of Equal Weight (30)

1053. Path of Equal Weight (30)

时间限制
10 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weight of a path from R to L is defined to be the sum of the weights of all the nodes along the path from R to any leaf node L.

Now given any weighted tree, you are supposed to find all the paths with their weights equal to a given number. For example, let's consider the tree showed in Figure 1: for each node, the upper number is the node ID which is a two-digit number, and the lower number is the weight of that node. Suppose that the given number is 24, then there exists 4 different paths which have the same given weight: {10 5 2 7}, {10 4 10}, {10 3 3 6 2} and {10 3 3 6 2}, which correspond to the red edges in Figure 1.


Figure 1

Input Specification:

Each input file contains one test case. Each case starts with a line containing 0 < N <= 100, the number of nodes in a tree, M (< N), the number of non-leaf nodes, and 0 < S < 230, the given weight number. The next line contains N positive numbers where Wi (<1000) corresponds to the tree node Ti. Then M lines follow, each in the format:

ID K ID[1] ID[2] ... ID[K]

where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID's of its children. For the sake of simplicity, let us fix the root ID to be 00.

Output Specification:

For each test case, print all the paths with weight S in non-increasing order. Each path occupies a line with printed weights from the root to the leaf in order. All the numbers must be separated by a space with no extra space at the end of the line.

Note: sequence {A1, A2, ..., An} is said to be greater than sequence {B1, B2, ..., Bm} if there exists 1 <= k < min{n, m} such that Ai = Bi for i=1, ... k, and Ak+1 > Bk+1.

Sample Input:
20 9 24
10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2
00 4 01 02 03 04
02 1 05
04 2 06 07
03 3 11 12 13
06 1 09
07 2 08 10
16 1 15
13 3 14 16 17
17 2 18 19
Sample Output:
10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2

提交代码

这道题的测试数据有漏洞:

例子:A节点的子节点插入时,只根据A的子节点的值的大小就决定了先后顺序。如果要求最后的和为10,A(v=3)的子节点有

B(v=2,子节点F(v=4,子节点G(v=1)))

C(v=2,子节点H(v=3,子节点I(v=2)))

D(v=4)

E(v=3),如果只根据一层的节点的值大小进行排序,(BC节点本身值相同时,根据其他条件判断BC的优先级,我写的代码中是按值相同情况下,再按序号降序排列)则恰巧C排在B后面,那么输出的序列应该先是A C H I和A B F G,但实际上根据题意输出序列应该是A B F G和A C H I,故测试数据有漏洞。

不信的话,可以将正文代码的20行  return a.num<num;  改为   return a.num>num;  再进行评判。  

其实真的要做,恐怕要把每条路径记录后,进行比较后才能输出。

注意点:

1.计入子节点的时候,要对子节点进行排序,值较大的放在前面,方便后面的深度优先遍历。

2.注意树可能为空,根节点可能就直接符合条件。

3.关于set的比较函数:

set的比较函数的条件一定要能比出最终的结果,在每一级的比较条件排序后,最后一定能完全地比较出大小。(不存在优先级相等的元素)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<queue>
 6 #include<vector>
 7 #include<cmath>
 8 #include<string>
 9 #include<map>
10 #include<set>
11 #include<stack>
12 using namespace std;
13 struct node{
14     int num,v;
15     bool operator<(const node &a) const {
16         return a.v<v;
17     }
18 };
19 node value[3];
20 map<int,set<node> > tree;
21 int main(){
22     //freopen("D:\INPUT.txt","r",stdin);
23     value[0].v=-1;
24     value[0].num=0;
25     tree[0].insert(value[0]);
26     value[1].v=-1;
27     value[1].num=1;
28     tree[0].insert(value[1]);
29     value[2].v=1;
30     value[2].num=2;
31     tree[0].insert(value[2]);
32     int i;
33 
34     cout<<tree[0].size()<<endl;
35 
36     set<node>::iterator it;
37     for(it=tree[0].begin();it!=tree[0].end();it++){
38         cout<<it->num<<endl;
39     }
40     /*int n,m,s;
41     scanf("%d %d %d",&n,&m,&s);
42     int i,j;
43     for(i=0;i<n;i++){
44         scanf("%d",value[i].v);
45         value[i].num=i;
46     }
47     int fir,num,amount;
48     for(i=0;i<m;i++){
49         scanf("%d %d",&fir,&amount);
50         for(j=0;j<amount;j++){
51             scanf("%d",&num);
52             tree[fir].insert(value[num]);
53         }
54     }*/
55 
56     return 0;
57 }

代码如下:

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<queue>
  6 #include<vector>
  7 #include<cmath>
  8 #include<string>
  9 #include<map>
 10 #include<set>
 11 #include<stack>
 12 using namespace std;
 13 struct node //set比较函数中的比较条件不能出现相同,一定要能完全比较
 14 {
 15     int num,v;
 16     bool operator<(const node &a) const  //降序
 17     {
 18         if(a.v==v)
 19         {
 20             return a.num<num;
 21         }
 22         return a.v<v;
 23     }
 24 };
 25 node value[105];
 26 map<int,set<node> > tree;
 27 int path[105];//记录前一个节点编号
 28 int n,m,s;
 29 queue<int>  qq;
 30 void DFS(int cur)
 31 {
 32     set<node>::iterator it;
 33     for(it=tree[cur].begin(); it!=tree[cur].end(); it++)
 34     {
 35         value[it->num].v=value[cur].v+value[it->num].v;
 36 
 37         //cout<<"father:  "<<cur<<"   "<<it->num<<"   "<<it->v<<"   "<<value[it->num].v<<endl;
 38 
 39         if(!tree[it->num].size()&&value[it->num].v==s) //找到符合条件的叶节点
 40         {
 41             qq.push(it->num);
 42         }
 43         else
 44         {
 45             if(value[it->num].v>s) //剪枝
 46             {
 47                 continue;
 48             }
 49             DFS(it->num);//q.push(it->num);
 50         }
 51     }
 52 }
 53 int main()
 54 {
 55     //freopen("D:\INPUT.txt","r",stdin);
 56     scanf("%d %d %d",&n,&m,&s);
 57     int i,j;
 58     for(i=0; i<n; i++)
 59     {
 60         scanf("%d",&value[i].v);
 61         value[i].num=i;
 62     }
 63     int fir,num,amount;
 64     path[0]=0;
 65     for(i=0; i<m; i++) //链接表
 66     {
 67         scanf("%d %d",&fir,&amount);
 68         for(j=0; j<amount; j++)
 69         {
 70             scanf("%d",&num);
 71             path[num]=fir;
 72             tree[fir].insert(value[num]);
 73         }
 74     }
 75     //queue<int>  q,qq;
 76     if(value[0].v==s){
 77         printf("%d
",s);
 78     }
 79     DFS(0);
 80     /*q.push(0);
 81     int cur;
 82     set<node>::iterator it;
 83     while(!q.empty()){
 84         cur=q.front();
 85         q.pop();
 86         for(it=tree[cur].begin();it!=tree[cur].end();it++){
 87             value[it->num].v=value[cur].v+value[it->num].v;
 88 
 89             cout<<"father:  "<<cur<<"   "<<it->num<<"   "<<it->v<<"   "<<value[it->num].v<<endl;
 90 
 91             if(!tree[it->num].size()&&value[it->num].v==s){//找到符合条件的叶节点
 92                 qq.push(it->num);
 93             }
 94             else{
 95                 if(value[it->num].v>s){//剪枝
 96                     continue;
 97                 }
 98                 q.push(it->num);
 99             }
100         }
101     }*/
102     while(!qq.empty())
103     {
104         stack<int> out;
105         int f=qq.front();
106         qq.pop();
107         for(i=f; path[i]!=i; i=path[i])
108         {
109             out.push(i);
110         }
111         printf("%d",f=value[i].v);//out.push(i);
112         while(!out.empty())
113         {
114             printf(" %d",value[out.top()].v-f);
115             f=value[out.top()].v;
116             out.pop();
117         }
118         printf("
");
119     }
120     return 0;
121 }
原文地址:https://www.cnblogs.com/Deribs4/p/4772687.html