1.练习项目 :
问题描述
给定一棵树,树中包含 n 个结点,编号为 1∼n ,以及 n−1 条无向边,每条边都有一个权值。
现从树中任选一个点,从该点出发,在不走回头路的情况下找出二条到其他点的路径,这二条路径不能有公共边,请问这二条路径长度的乘积最大可以是多少。
注:如果从该点出发只有一个方向可以走,换句话说该点入度出度为 1,则乘积为 0 。
输入格式
第一行输入一个整数 n。
接下来 n−1 行,每行输入包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。
输出格式
输出一个整数,为二条路径长度乘积的最大值。
2.选择课程
在蓝桥云课中选择题库,选择题号3649并开始练习。
3.开始练习
(1)源码 :
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e5+10;
int n;
vector<pair<int,int>>g[N];
int d1[N],d2[N],p1[N],p2[N],up[N];
void dfs1(int u,int f)
{
for(const auto&v:g[u]){
if(v.first==f)continue;
dfs1(v.first,u);
int len=v.second+d1[v.first];
if(len>=d1[u]){
d2[u]=d1[u];
p2[u]=p1[u];
d1[u]=len;
p1[u]=v.first;
}else if(len>d2[u]){
d2[u]=len;
p2[u]=v.first;
}
}
}
void dfs2(int u,int f)
{
for(const auto&v:g[u]){
if(v.first==f)continue;
if(p1[u]==v.first){
up[v.first]=max(up[u],d2[u])+v.second;
}else{
up[v.first]=max(up[u],d1[u])+v.second;
}
dfs2(v.first,u);
}
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<n;i++){
int a,b,c;cin>>a>>b>>c;
g[a].push_back({b,c});
g[b].push_back({a,c});
}
dfs1(1,0);
dfs2(1,0);
ll ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,(ll)max((ll)d1[i]*d2[i],(ll)d1[i]*up[i]));
}
cout<<ans<<'\n';
return 0;
}
(2)检验结果
对此代码进行检验,检验后无报错,提交此代码,判题结果为正确100分。
(3)练习心得:
注意每段代码末尾的分号是否存在 ,如不存在则需即使补充;输入法 是否切换为英语模式;语法是否错误。