根据以下要求写一段c语言代码【输入形式】 多组数据。 每组数据第一行有一个整数n,表示竹子中的节点个数( 1<= n <=100000 )。 接下来有n-1行,每行三个整数a,b和w表示节点a和节点b之间有一个长度为w的竹枝( 1 <= a,b <= n ,1 <= w <= 100 )。 【输出形式】 输出最远的两个叶子的距离。 【样例输入】 7 1 2 1 2 4 1 2 5 1 1 3 1 3 6 1 3 7 1 【样例输出】 4
时间: 2024-03-17 18:43:12 浏览: 99
以下是参考代码:
```c
#include <stdio.h>
#include <string.h>
#define MAX_N 100005
typedef struct {
int v; // 与当前节点相连的节点编号
int w; // 边权重
int next; // 下一条边的编号
} Edge;
int head[MAX_N]; // 存储每个节点的邻接表的头结点编号
Edge edges[MAX_N * 2]; // 存储所有的边
int edge_cnt = 0; // 当前边的数量
int max(int x, int y) {
return x > y ? x : y;
}
int dfs(int u, int fa, int *max_depth) {
// 记录当前节点的最大深度和次大深度
int max_depth1 = 0, max_depth2 = 0;
// 遍历当前节点的所有邻接节点
for (int i = head[u]; i != -1; i = edges[i].next) {
int v = edges[i].v;
int w = edges[i].w;
if (v != fa) {
// 如果当前节点不是父节点,就递归遍历它的子树
int depth = dfs(v, u, max_depth) + w;
if (depth > max_depth1) {
// 如果当前深度比最大深度还要大,就更新最大深度和次大深度
max_depth2 = max_depth1;
max_depth1 = depth;
} else if (depth > max_depth2) {
// 否则如果当前深度比次大深度还要大,就更新次大深度
max_depth2 = depth;
}
}
}
// 计算当前节点的最大深度和它的子树中最大深度的和
*max_depth = max(*max_depth, max_depth1 + max_depth2);
return max_depth1;
}
int main() {
int n;
while (scanf("%d", &n) == 1) {
// 初始化邻接表
memset(head, -1, sizeof(head));
edge_cnt = 0;
// 输入边
for (int i = 0; i < n - 1; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
// 添加一条从 u 到 v 的边
edges[edge_cnt].v = v;
edges[edge_cnt].w = w;
edges[edge_cnt].next = head[u];
head[u] = edge_cnt;
edge_cnt++;
// 添加一条从 v 到 u 的边
edges[edge_cnt].v = u;
edges[edge_cnt].w = w;
edges[edge_cnt].next = head[v];
head[v] = edge_cnt;
edge_cnt++;
}
// 从根节点进行 DFS,求出最远的两个叶子的距离
int max_depth = 0;
dfs(1, 0, &max_depth);
printf("%d\n", max_depth);
}
return 0;
}
```
代码思路和之前的解题思路一致,使用一个邻接表来存储图的信息,使用 DFS 来遍历每个节点。在 DFS 的过程中,对于每个节点,记录它的最大深度和次大深度,并计算出它的最大深度和它的子树中最大深度的和。最后就可以得到最远的两个叶子的距离。
这里使用了一个结构体 `Edge` 来存储边的信息,包括与当前节点相连的节点编号 `v`,边的权重 `w`,以及下一条边的编号 `next`。同时还使用了一个数组 `head` 来存储每个节点的邻接表的头结点编号,以及一个计数器 `edge_cnt` 来记录当前边的数量。
阅读全文