牛客练习赛24 D 插排树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
链接:https://www.nowcoder.com/acm/contest/157/D 来源:牛客网 题目描述 一年一度的山东省oi夏令营又开始了,每到这个季节,山东的oier们都会欢聚这里,一起学(tuí)习(feì)。当然,为了能更加愉快地学(tuí)习(feì),就少不了要自带电脑,用电便开始成了一种问题,于是便有一种神奇的数据结构诞生了!这就是山东省oi专用数据结构——插排树(如图) 小K为了能更好的学(tuí)习(feì),所以他想尽量的往后做,所以现在请你帮帮他,他最远可以离讲台多远。 已知插排树的根节点在讲台上,有且仅有一个根节点(根节点入度为0),最远距离即所有插排的长度,小K电脑线的长度忽略不计 本题良心大样例下载地址: https://kench.co/tree.zip 输入描述: 第一行一个整数n表示有n个节点然后n-1行,每行三个整数a,b,c,表示插排a是接在插排b上的,插排a的长度为c 输出描述: 一个整数n表示最远距离 示例1 输入 复制 9 2 1 2 3 1 2 4 1 1 5 2 3 6 2 1 7 3 1 8 3 4 9 7 5 输出 复制 8 说明 1=>3=>7=>9 备注: 对于30%的数据 n<233对于70%的数据 n<2333对于100%的数据 n<50000c小于20a,b小于等于n
我的思路:dfs,搜索每一个结点直到这个结点没有连接的结点为止,用vector数组存储结构体,下标保存b,结构体保存尾结点和长度
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> using namespace std; int maxn=0; struct point { int a; int l; }; vector<point> pp[50005]; void dfs(int k,int len) { if(maxn<len) maxn=len; for(int i=0;i<pp[k].size();i++) { dfs(pp[k][i].a,len+pp[k][i].l); } } int main() { int n,a,b,c,x[50005]; int z=0; memset(x,0,sizeof(x)); scanf("%d",&n); for(int i=0;i<n-1;i++) { scanf("%d%d%d",&a,&b,&c); x[a]=1; point p; p.a=a; p.l=c; pp[b].push_back(p); } for(int i=1;i<=n;i++) { if(x[i]==0) dfs(i,0); } cout<<maxn<<endl; return 0; }
然后我在别人提交的代码中看到一个很简单的办法,用一个数组存储每个点的长度,输入abc三个,a=b+c,用数组dis存储即dis[a]=dis[b]+c
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; int dis[50005]; int main() { int n,a,b,c,ans=0; scanf("%d",&n); for(int i=0;i<n-1;i++) { scanf("%d%d%d",&a,&b,&c); dis[a]=dis[b]+c; } for(int i=0;i<n;i++) { ans=max(ans,dis[i]); } printf("%d\n",ans); return 0; }