题目
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
即给一棵树,输出所有从根到叶权重和等于s的路径上个点的权重。
多条路线按照减序(从根到叶逐个比较)输出。
输入,dfs或bfs探测树,
探测过程中保留路径信息和总权重信息,每当到达叶节点时如果权重和等于S则暂存,
排序输出。
代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct node //用于路径探测的点
{
int id; //探测到的点
int weight; //到该点的总重量
vector<int> path; //到该点的路径
};
bool cm(const vector<int> v1,const vector<int> v2); //按权重排序
int main()
{
int n,m,s; //输入数据
int weight[100]; //各个点的权重
vector<int> child[100]; //各个点的孩子
cin>>n>>m>>s;
int node_id,num_child,temp,i,j; //某个点的id,某个点的孩子数,某个点的孩子临时输入数据
for(i=0;i<n;i++) //输入信息
scanf("%d",&weight[i]);
for(i=0;i<m;i++)
{
scanf("%d %d",&node_id,&num_child);
for(j=0;j<num_child;j++)
{
scanf("%d",&temp);
child[node_id].push_back(temp);
}
}
node node1,node2; //探测用临时点
queue<node> path_test; //广度优先……一开始看成按标号排序了,用深度会效率更高些,无所谓
vector<vector<int>> paths; //存储符合条件的各条路径
vector<int> weight_path; //符合条件的路的临时数据
node1.id=0; //压入根节点
node1.weight=weight[0];
node1.path.push_back(0);
path_test.push(node1);
while(!path_test.empty()) //广度优先
{
node1=path_test.front();
path_test.pop();
if(!child[node1.id].empty()) //非叶节点,压入孩子
{
for(i=0;i<child[node1.id].size();i++)
{
node2.id=child[node1.id][i];
node2.weight=node1.weight+weight[node2.id];
node2.path=node1.path;
node2.path.push_back(node2.id);
path_test.push(node2);
}
}
else if(node1.weight==s) //叶节点,且符合条件
{
weight_path.clear();
for(i=0;i<node1.path.size();i++)
weight_path.push_back(weight[node1.path[i]]);
paths.push_back(weight_path);
}
}
sort(paths.begin(),paths.end(),cm); //排序
for(i=0;i<paths.size();i++) //输出
{
printf("%d",paths[i][0]);
for(j=1;j<paths[i].size();j++)
printf(" %d",paths[i][j]);
printf("\n");
}
return 0;
}
bool cm(const vector<int> v1,const vector<int> v2)
{
int size,i;
if(v1.size()<v2.size())
size=v1.size();
else
size=v2.size();
for(i=0;i<size;i++)
{
if(v1[i]>v2[i])
return true;
else if(v1[i]<v2[i])
return false;
}
if(size<v1.size())
return true;
else
return false;
}