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)