1072. 树的最长路径(树形DP)
题目:https://www.acwing.com/problem/content/1074/
题意:n个点n-1条边的无向图树,每条边都有一个权值,可正可负,求最大权值。
题解:树形dp,,任取一个点为根节点,记录每个节点往下搜的所有路径的权值,找到最大权值和第二大权值,以这个点为核心的最大权值的路径就是这俩权值和。
#include <algorithm> #include <bitset> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <deque> #include <functional> #include <iostream> #include <map> #include <queue> #include <set> #include <stack> #include <string> #include <vector> //#include <unordered_map> //#include <unordered_set> //#include <bits/stdc++.h> //#define int long long #define pb push_back #define PII pair<int, int> #define mpr make_pair #define ms(a, b) memset((a), (b), sizeof(a)) #define x first #define y second typedef long long ll; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const int N = 10010, M = 2 * 10010; const double eps = 1e-8; using namespace std; int n; int h[N],e[M],w[M],ne[M],idx; int ans; void add(int u,int v,int val){ e[idx]=v,w[idx]=val,ne[idx]=h[u],h[u]=idx++; } int dfs(int u,int fa){ //u是当前节点,fa是父亲节点 int d1=0,d2=0; //d1,d2表示子树的第一大权值和第二大权值 for(int i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa)continue;//防止找父亲节点,无限循环 int d=dfs(j,u)+w[i]; //这个子节点的权值 if(d>=d1)d2=d1,d1=d; //确定第一大权值和第二大权值 else if(d>d2)d2=d; } ans=max(ans,d1+d2); //取这个点的第一大权值和第二大权值之和,构成这条链 return d1; //返回最大权值 } signed main(int argc, char const *argv[]) { memset(h,-1,sizeof(h)); cin>>n; for(int i=0;i<n-1;i++){ int u,v,val; cin>>u>>v>>val; add(u,v,val),add(v,u,val); } dfs(1,-1); cout<<ans<<endl; return 0; }

浙公网安备 33010602011771号