1053 Path of Equal Weight

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1053 Path of Equal Weight相关的知识,希望对你有一定的参考价值。

1. 这道题考察的是树(注意不是二叉树,子结点个数不限,没有顺序)的先根遍历,即DFS,因为BFS做不到把祖先节点的值累计到当前结点。我这里使用了一个copyDadWeis函数实现,把父节点的权重向量拷贝给子节点,在先根遍历、每次开始递归调用前调用这个函数。

2. 结点结构体Node包括:1个LL型的数据域(存放权重),1个int型向量存放子节点下标,1个LL向量存放祖先节点和当前结点权重。

struct Node{
	LL wei;
	vector<int> children;
	vector<LL> weis;
}node[maxn];

3. 采用静态写法,也即用数组存放结点,数组下标为结点的序号。

4. 其实这题最最头疼的地方是仿佛最简单的:怎么把符合要求的权重序列,按照从大到小的顺序输出。一开始的思路是得到这些序列以后,进行排序,但是始终完成不了。其实排序应该在写入的过程中就开始了,也就是读到每一个结点的叶子节点,先不急着放进叶子向量,而是借用一个数组将其按照对应节点权重非升序排列后,再存进向量。

    for(int i=0;i<nonLeaf_n;i++){
		scanf("%d",&now);
		scanf("%d",&children_n);
		int temp[maxn] = {0};
		for(int j=0;j<children_n;j++)scanf("%d",&temp[j]);
		sort(temp,temp+children_n,cmp);//让编号对应权重大的结点提前 
		for(int j=0;j<children_n;j++){
			node[now].children.push_back(temp[j]);
		}
	}

这样还不够,如果还是像留到最后一块判断,那么之前的努力就白费了,必须是在DFS的过程中,遇到叶子节点就判断权重向量和。因为DFS的顺序是符合同层大权重在先的顺序的。

AC代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
typedef long long LL;

using namespace std;

const int maxn = 110;
 
LL target;

void copyDadWeis(vector<LL>& child,vector<LL>& dad){//地址符号不可缺少,否则将不能在原向量上改动 
	int size = dad.size();
	for(int i=0;i<size;i++){
		child.push_back(dad[i]);
	}
	return;
}

LL getSum(vector<LL> weis){
	int size = weis.size();
	LL sum = 0;
	for(int i=0;i<size;i++){
		sum += weis[i];
	}
	return sum;
} 
 
struct Node{
	LL wei;
	vector<int> children;
	vector<LL> weis;
}node[maxn];

void preOrder(int root){//先根遍历 
	node[root].weis.push_back(node[root].wei);//把自身权重加进去
	if(node[root].children.size()){//说明不是叶子结点 
		for(int i=0;i<node[root].children.size();i++){
			//把父节点的权重容器拷贝过来
			int childIdx = node[root].children[i];
			copyDadWeis(node[childIdx].weis,node[root].weis);
			preOrder(childIdx); 
		}
	}else{//是叶子结点 
		if(getSum(node[root].weis)==target){//是符合要求的叶子 
			int size = node[root].weis.size();
			for(int j=0;j<size;j++){
				printf("%lld",node[root].weis[j]);
				if(j!=size-1)printf(" ");
			}
			printf("\\n");
		}
	} 
	 
}

bool cmp(int a,int b){
	return node[a].wei>node[b].wei;
} 


int main(){
	int node_n,nonLeaf_n,children_n;
	int now,child;
	
	
	scanf("%d%d%lld",&node_n,&nonLeaf_n,&target);
	
	for(int i=0;i<node_n;i++)scanf("%lld",&node[i].wei);
	
	for(int i=0;i<nonLeaf_n;i++){
		scanf("%d",&now);
		scanf("%d",&children_n);
		int temp[maxn] = {0};
		for(int j=0;j<children_n;j++)scanf("%d",&temp[j]);
		sort(temp,temp+children_n,cmp);//让编号对应权重大的结点提前 
		for(int j=0;j<children_n;j++){
			node[now].children.push_back(temp[j]);
		}
	}
	
	preOrder(0);
		
	
	 
	return 0;
}

以上是关于1053 Path of Equal Weight的主要内容,如果未能解决你的问题,请参考以下文章

PAT 1053. Path of Equal Weight

PAT 1053 Path of Equal Weight (30)

1053 Path of Equal Weight

1053 Path of Equal Weight

PAT 1053. Path of Equal Weight (30)

PAT Advanced Level 1053 Path of Equal Weight