PTA-树的遍历(1079/1090/1094/1106/1004/1053)

10 篇文章 0 订阅
7 篇文章 0 订阅

1079 Total Sales of Supply Chain (25 分)

A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. Only the retailers will face the customers. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the total sales from all the retailers.

Input Specification:

Each input file contains one test case. For each case, the first line contains three positive numbers: N (≤10 5), the total number of the members in the supply chain (and hence their ID’s are numbered from 0 to N−1, and the root supplier’s ID is 0); P, the unit price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:Ki ID[1] ID[2] … ID[K i ]
where in the i-th line, K iis the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. Kjbeing 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after K j. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the total sales we can expect from all the retailers, accurate up to 1 decimal place. It is guaranteed that the number will not exceed 1010.

Sample Input:

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

Sample Output:

42.4

思路

树的遍历的模板题,bfs给每层结点带上层号,最后输出所有叶子结点的权值*比率的层级次方即可。

#include<bits/stdc++.h>
using namespace std;
int n;
double price,rate;
struct node{
	int data;
	int layer;
	vector<int> child;
};
vector<node> ans;
void bfs(int root){
	queue<int> que;
	que.push(root);
	ans[root].layer=0;
	while(!que.empty()){
		int one=que.front();
		que.pop();
		for(int i=0;i<ans[one].child.size();i++){
			int kid=ans[one].child[i];
			ans[kid].layer=ans[one].layer+1;
			que.push(kid);
		}
	}
}
int main(){
	cin>>n>>price>>rate;
	ans.resize(n);
	int num;
	int son;
	for(int i=0;i<n;i++){
		cin>>num;
		if(num==0){
			cin>>son;
			ans[i].data=son;
			continue;
		} 
		while(num--){
			cin>>son;
			ans[i].child.push_back(son);
		}
	}
	bfs(0);
	double sum=0;
	for(int i=0;i<ans.size();i++){
		if(ans[i].data!=0){
			sum+=ans[i].data*price*pow(1+rate*0.01,ans[i].layer);
		}
	}
	printf("%.1lf",sum);
	return 0;
}

1090 Highest Price in Supply Chain (25 分)

A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the highest price we can expect from some retailers.

Input Specification:

Each input file contains one test case. For each case, The first line contains three positive numbers: N (≤10 5), the total number of the members in the supply chain (and hence they are numbered from 0 to N−1); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then the next line contains N numbers, each number S iis the index of the supplier for the i-th member. S rootfor the root supplier is defined to be −1. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the highest price we can expect from some retailers, accurate up to 2 decimal places, and the number of retailers that sell at the highest price. There must be one space between the two numbers. It is guaranteed that the price will not exceed 1010.

Sample Input:

9 1.80 1.00
1 5 4 4 -1 4 5 3 6

Sample Output:

1.85 2

思路

这道题和上一道类似,比上一道还简单些,bfs带上层号后,排序得到最大层数的叶子结点个数,处理输出即可。

#include<bits/stdc++.h>
using namespace std;
struct node{
	int layer;
	vector<int> child;
};
vector<node> ans;
int n;
void bfs(int root){
	ans[root].layer=0;
	queue<int> que;
	que.push(root);
	while(!que.empty()){
		int one=que.front();
		que.pop();
		for(int i=0;i<ans[one].child.size();i++){
			int son=ans[one].child[i];
			ans[son].layer=ans[one].layer+1;
			que.push(son);
		}
	}
}
bool cmp(node a,node b){
	return a.layer>b.layer;
}
int main()
{
	double price,r;
	scanf("%d%lf%lf",&n,&price,&r);
	ans.resize(n);
	int root=0;
	for(int i=0;i<n;i++){
		int num;
		cin>>num;
		if(num==-1) root=i;
		else ans[num].child.push_back(i);
	}
	bfs(root);
	sort(ans.begin(),ans.end(),cmp);
	int path=ans[0].layer;
	int num=1;
	for(int i=0;i<ans.size();i++){
		if(ans[i].layer!=path){
            num=i;
			break;
		}
	}
	printf("%.2lf %d",price*pow((1+r*0.01),path),num);
	return 0;
}

1094 The Largest Generation (25 分)

A family hierarchy is usually presented by a pedigree tree where all the nodes on the same level belong to the same generation. Your task is to find the generation with the largest population.

Input Specification:

Each input file contains one test case. Each case starts with two positive integers N (<100) which is the total number of family members in the tree (and hence assume that all the members are numbered from 01 to N), and M (<N) which is the number of family members who have children. Then M lines follow, each contains the information of a family member in the following format:

ID K ID[1] ID[2] … ID[K]
where ID is a two-digit number representing a family member, K (>0) is the number of his/her children, followed by a sequence of two-digit ID’s of his/her children. For the sake of simplicity, let us fix the root ID to be 01. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the largest population number and the level of the corresponding generation. It is assumed that such a generation is unique, and the root level is defined to be 1.

Sample Input:

23 13
21 1 23
01 4 03 02 04 05
03 3 06 07 08
06 2 12 13
13 1 21
08 2 15 16
02 2 09 10
11 2 19 20
17 1 22
05 1 11
07 1 14
09 1 17
10 1 18

Sample Output:

9 4

思路

输出拥有叶子结点数最多的层的叶子结点数以及层号。
dfs给树的结点带上层号,同时判定若此结点为叶子,在哈希表中将层号对应的值++,最后遍历哈希表,找到最大的数目即可。

#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	int layer;
	vector<int> child;
};
vector<node> ans;
vector<int> number(101);
void dfs(int root,int layer){
	ans[root].layer=layer;
	number[layer]++;
	if(ans[root].child.empty()){
		return ;
	}
	for(int i=0;i<ans[root].child.size();i++){
		int kid=ans[root].child[i];
		dfs(kid,layer+1);
	}
}
int main()
{
	int m;
	cin>>n>>m;
	ans.resize(n+1);
	int no,num,kid;
	while(m--){
		cin>>no>>num;
		while(num--){
			cin>>kid;
			ans[no].child.push_back(kid);
		}
	}
	dfs(1,0);
	int sum=0,k=0;
	for(int i=0;i<number.size();i++){
		if(number[i]>sum){
			sum=number[i];
			k=i+1;
		}
	}
	cout<<sum<<' '<<k;
	return 0;
}

1106 Lowest Price in Supply Chain (25 分)

A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. Only the retailers will face the customers. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the lowest price a customer can expect from some retailers.

Input Specification:

Each input file contains one test case. For each case, The first line contains three positive numbers: N (≤10 5), the total number of the members in the supply chain (and hence their ID’s are numbered from 0 to N−1, and the root supplier’s ID is 0); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:
K i ID[1] ID[2] … ID[K i ]where in the i-th line, K i is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. Kjbeing 0 means that the j-th member is a retailer. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the lowest price we can expect from some retailers, accurate up to 4 decimal places, and the number of retailers that sell at the lowest price. There must be one space between the two numbers. It is guaranteed that the all the prices will not exceed 10 10.

Sample Input:

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0
2 6 1
1 8
0
0
0

Sample Output:

1.8362 2

思路

与前面的题类似,dfs为节点带上层号后,遍历找到深度最少的叶子结点的深度及个数,处理输出数据即可。

#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	int layer;
	vector<int> child;
};
vector<node> ans;
void dfs(int root,int layer){
	ans[root].layer=layer;
	if(ans[root].child.empty()){
		return ;
	}
	for(int i=0;i<ans[root].child.size();i++){
		int kid=ans[root].child[i];
		dfs(kid,layer+1);
	}
}
int main()
{
	double price,rate;
	cin>>n>>price>>rate;
	ans.resize(n);
	int num,kid;
	for(int i=0;i<n;i++){
		cin>>num;
		while(num--){
			cin>>kid;
			ans[i].child.push_back(kid);
		}
	} 
	dfs(0,0);
	num=1;
	int sum=INT_MAX;
	for(int i=0;i<ans.size();i++){
		if(ans[i].child.empty()){
			if(ans[i].layer<sum){
				sum=ans[i].layer;
				num=1;		
			} else if(ans[i].layer==sum){
				num++;
			}
		}
	}
	double tot=price*pow(1+rate*0.01,sum);
	printf("%.4lf %d",tot,num);
	return 0;
}

1004 Counting Leaves (30 分)

A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.

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, and M (<N), the number of non-leaf nodes. 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 01.

The input ends with N being 0. That case must NOT be processed.

Output Specification:

For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.

The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output 0 1 in a line.

Sample Input:

2 1
01 1 02

Sample Output:

0 1

思路

输出每一层的叶子结点个数,dfs带上层号过程中,进行哈希映射,最后输出哈希表的值即可,注意根结点是1而不是0!

#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	int layer;
	vector<int> child;
};
vector<node> ans;
vector<int> vec(101);
int layer_max;
void dfs(int root,int layer){
	ans[root].layer=layer;
	if(layer>layer_max) layer_max=layer;
	if(ans[root].child.empty()){
		vec[layer]++;
		return ;
	} 
	for(int i=0;i<ans[root].child.size();i++){
		int kid=ans[root].child[i];
		dfs(kid,layer+1);
	}
}
int main()
{
	int m;
	cin>>n>>m;
	if(!n) return 0;
	ans.resize(n+1);
	int no,num,kid;
	while(m--){
		cin>>no>>num;
		while(num--){
			cin>>kid;
			ans[no].child.push_back(kid);
		}
	}
	dfs(1,0);
	for(int i=0;i<=layer_max;i++){
		cout<<vec[i];
		if(i!=layer_max) cout<<' ';
	}
	return 0;
}

1053 Path of Equal Weight (30 分)

Given a non-empty tree with root R, and with weight W iassigned to each tree node T i . 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 the following figure: 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 the figure.

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<2 30, the given weight number. The next line contains N positive numbers where W i (<1000) corresponds to the tree node T i. 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 {A 1,A 2,⋯,A n } is said to be greater than sequence {B 1 ,B 2 ,⋯,B m} if there exists 1≤k<min{n,m} such that A i=B ifor i=1,⋯,k, and A k+1 >B
k+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
Special thanks to Zhang Yuan and Yang Han for their contribution to the judge’s data.

思路

#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
	vector<int> child;
};
int n,m,value;
vector<node> ans;
vector<int> path;
void dfs(int root,int layer,int sum){
	if(sum>value) return ;
	if(sum==value){
		if(!ans[root].child.empty()) return ;
		for(int i=0;i<=layer;i++){
			cout<<path[i];
			if(i!=layer) cout<<' ';
			else cout<<endl;
		}
	}
	for(int i=0;i<ans[root].child.size();i++){
		int kid=ans[root].child[i];
		path[layer+1]=ans[kid].data;
		dfs(kid,layer+1,sum+ans[kid].data);
	}
}
bool cmp(int a,int b){
	return ans[a].data>ans[b].data;
}
int main()
{
	cin>>n>>m>>value;
	ans.resize(n);
	path.resize(n);
	for(int i=0;i<n;i++){
		cin>>ans[i].data;
	}
	int no,num,kid;
	while(m--){
		cin>>no>>num;
		while(num--){
			cin>>kid;
			ans[no].child.push_back(kid);
		}
		sort(ans[no].child.begin(),ans[no].child.end(),cmp);
	}
	path[0]=ans[0].data;
	dfs(0,0,ans[0].data);
	return 0;
}

思路

在输入后对子节点进行排序可以优先找到结点号较大的子节点序列。
dfs进行搜索:
如果大于输入的value直接返回不成立;
如果等于value,若当前节点还有子节点,说明总路径一定大于value,返回不成立;若没有则输出当前的path序列;
对该结点的每一个叶子结点进行dfs,与模板无二。

#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
	vector<int> child;
};
int n,m,value;
vector<node> ans;
vector<int> path;
void dfs(int root,int layer,int sum){
	if(sum>value) return ;
	if(sum==value){
		if(!ans[root].child.empty()) return ;
		for(int i=0;i<=layer;i++){
			cout<<path[i];
			if(i!=layer) cout<<' ';
			else cout<<endl;
		}
	}
	for(int i=0;i<ans[root].child.size();i++){
		int kid=ans[root].child[i];
		path[layer+1]=ans[kid].data;
		dfs(kid,layer+1,sum+ans[kid].data);
	}
}
bool cmp(int a,int b){
	return ans[a].data>ans[b].data;
}
int main()
{
	cin>>n>>m>>value;
	ans.resize(n);
	path.resize(n);
	for(int i=0;i<n;i++){
		cin>>ans[i].data;
	}
	int no,num,kid;
	while(m--){
		cin>>no>>num;
		while(num--){
			cin>>kid;
			ans[no].child.push_back(kid);
		}
		sort(ans[no].child.begin(),ans[no].child.end(),cmp);
	}
	path[0]=ans[0].data;
	dfs(0,0,ans[0].data);
	return 0;
}

ps:PTA应该是修改了后台的数据,解答的代码均无法通过最后一个测试点
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新西兰做的饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值