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的主要内容,如果未能解决你的问题,请参考以下文章