URAL 1018 Binary Apple Tree (树形DP)

本文详细介绍了使用C语言实现深度优先搜索(DFS)算法,解决了一个涉及苹果树枝干最大苹果数量的问题。通过定义结构体、数组和函数,作者展示了如何在有限的枝干和点之间计算每个点的最大苹果数量。此过程涉及到递归调用和数组的高效使用,最终输出所有枝干中最大的苹果数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#define MAX_POINTS 100
#define MAX(x, y) ( (x) > (y) ? (x) : (y) )


typedef struct Branch{
int to;
int apples;
int next;
}Branch;
Branch BranchArray[MAX_POINTS * 2];
int BranchNum;
int head[MAX_POINTS + 1];
int branches[MAX_POINTS + 1];
//maxApple[point][preBranches]表示点point的前preBreanches个枝干branch的最大苹果数
int maxApples[MAX_POINTS + 1][MAX_POINTS + 1];
int visited[MAX_POINTS + 1];
int numOfPoints, numOfBranchesPreserved;


void addBranch(int from, int to, int apples){
BranchNum++;
BranchArray[BranchNum].to = to;
BranchArray[BranchNum].apples = apples;
BranchArray[BranchNum].next = head[from];
head[from] = BranchNum;
}


void dfs(int fromParent, int from){
int leftChild = 0;
int rightChild = 0;
int leftApples = 0;
int rightApples = 0;
int i;
for (i = head[from]; i != 0; i = BranchArray[i].next){
if (BranchArray[i].to == fromParent)
continue;
if (leftChild == 0){
leftChild = BranchArray[i].to;
leftApples = BranchArray[i].apples;
if (visited[leftChild] == 0){
visited[leftChild] = 1;
dfs(from, leftChild);
}
} else {
rightChild = BranchArray[i].to;
rightApples = BranchArray[i].apples;
if (visited[rightChild] == 0){
visited[rightChild] = 1;
dfs(from, rightChild);
}
}
}

//只有一个枝干的情况,左枝干或者右枝干
maxApples[from][1] = MAX(leftApples, rightApples);


int temp = leftApples + rightApples;


int j;
for (i = 2; i <= numOfBranchesPreserved; i++){
//枝干全在左边,或者全在右边
maxApples[from][i] = MAX(maxApples[leftChild][i - 1] + leftApples, maxApples[rightChild][i - 1] + rightApples);
for (j = 0; j <= i - 2; j++)
//一边至少有一个枝干
maxApples[from][i] = MAX(maxApples[from][i], maxApples[leftChild][j] + maxApples[rightChild][i - 2 - j] + temp);
}


}


int main(){


scanf("%d%d", &numOfPoints, &numOfBranchesPreserved);


int from, to, apples;
numOfPoints--;
while (numOfPoints--){
scanf("%d%d%d", &from, &to, &apples);
addBranch(from, to, apples);
addBranch(to, from, apples);
}


visited[1] = 1;
dfs(-1, 1);


printf("%d\n", maxApples[1][numOfBranchesPreserved]);


return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值