#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
#define ll long long
const int N = 1e5+5;
ll d1[N]; // 存储从根节点到当前节点的最大路径长度
ll d2[N]; //从树的根节点出发到某个节点的第二长的路径的长度(次大路径长度)
int p1[N]; // 存储从根节点到当前节点最大路径的上一个节点
int p2[N]; // 存储从根节点到当前节点次大路径的上一个节点
ll up[N]; // 存储从当前节点向上走的最大路径长度
vector<pair<int,int>> e[N];
//用于找到从根节点到每个节点的最大路径长度,同时记录下最大路径上的前一个节点
void dfs1(int t,int f){
for(auto &y:e[t]){
if(y.first==f) continue;
dfs1(y.first,t);
if(d1[y.first] + y.second >= d1[t]){ // 如果从y.first出发的路径长度加上边的权值大于等于当前节点t的路径长度
d2[t] = d1[t]; // 更新节点t的次大路径长度为最大路径长度
p2[t] = p1[t]; // 更新节点t的次大路径的上一个节点为最大路径的上一个节点
d1[t] = d1[y.first] + y.second; // 更新节点t的最大路径长度
p1[t] = y.first; // 更新节点t的最大路径的上一个节点
}
else if(d1[y.first] + y.second > d2[t]){ // 如果从y.first出发的路径长度加上边的权值大于节点t的次大路径长度
d2[t] = d1[y.first] + y.second; // 更新节点t的次大路径长度
p2[t] = y.first; // 更新节点t的次大路径的上一个节点
}
}
}
void dfs2(int t,int f){
for(auto &y:e[t]){
if(y.first == f) continue;
if(y.first == p1[t]){ // 如果边的另一端是节点t的最大路径的上一个节点
up[y.first] = y.second + max(up[t],d2[t]); // 更新从y.first向上走的最大路径长度
}
else { // 如果边的另一端不是节点t的最大路径的上一个节点
up[y.first] = y.second + max(up[t],d1[t]); // 更新从y.first向上走的最大路径长度
}
dfs2(y.first,t); // 递归调用dfs2
}
}
int main()
{
int n;
cin >> n;
for(int i = 1 ; i<=n-1 ;i++){
int u,v,d;
cin >> u >> v >> d;
e[u].push_back({v,d});
e[v].push_back({u,d});
}
dfs1(1,-1);
dfs2(1,-1);
ll ans = 0;
for(int i = 1 ; i <= n ; i++){
ll m = 0;
m = max(d1[i]*up[i],d2[i]*d1[i]); // 计算从节点i出发的两条路径长度乘积的最大值
ans = max(m,ans);
}
cout << ans ;
return 0;
}
最长乘积链 树形dp
最新推荐文章于 2024-07-25 11:27:31 发布