1.树的最长路径
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5a6d918de7c7216ad1e73fc329dd7ce2.png)
权值为非负时
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
int n;
int h[N],e[N*2],w[N*2],ne[N*2],idx;
int dist[N];
void add(int a,int b,int c){
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int father,int distance){
dist[u]=distance;
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if(j!=father)
dfs(j,u,distance+w[i]);
}
}
int main()
{
cin>>n;
memset(h,-1,sizeof h);
for(int i=0;i<n-1;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
dfs(1,-1,0);
int u=1;
for(int i=2;i<=n;i++){
if(dist[u]<dist[i])u=i;
}
dfs(u,-1,0);
for(int i=1;i<=n;i++)
if(dist[u]<dist[i])
u=i;
printf("%d\n", dist[u]);
}
权值有负数时,用树形DP思想
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 20010;
int e[N],ne[N],h[N],w[N],idx=0;
int res=0;
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dfs(int u,int fa)
{
int d1=0,d2=0,dis=0;
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];
dis=max(dis,d);
if(d>=d1)d2=d1,d1=d;
else if(d>d2)d2=d;
}
res=max(res,d1+d2);
return dis;
}
int main()
{
memset(h, -1, sizeof h);
int n;
cin>>n;
for(int i=1;i<n;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
dfs(1,-1);
cout<<res<<endl;
}
2.树的中心
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d52a9f269a82c4031eabc70266666df5.png)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 20010,INF=0x3f3f3f3f;
int n;
int e[N],h[N],ne[N],w[N],idx=0;
int d1[N],d2[N],p[N],up[N];
bool is_leaf[N];
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dfs_d(int u,int fa)
{
d1[u]=d2[u]=-INF;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa)continue;
int d=dfs_d(j,u)+w[i];
if(d>=d1[u])
{
d2[u]=d1[u];
d1[u]=d;
p[u]=j;
}
else if(d>d2[u])d2[u]=d;
}
if(d1[u]==-INF)
{
is_leaf[u]=true;
d1[u]=d2[u]=0;
}
return d1[u];
}
int dfs_u(int u,int fa)
{
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa)continue;
if(p[u]==j)up[j]=max(up[u],d2[u])+w[i];
else up[j]=max(up[u],d1[u])+w[i];
dfs_u(j,u);
}
}
int main()
{
cin>>n;
memset(h,-1,sizeof h);
for(int i=1;i<n;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
dfs_d(1,-1);
dfs_u(1,-1);
int res=INF;
for(int i=1;i<=n;i++)
{
if(is_leaf[i])res=min(res,up[i]);
else res=min(res,max(up[i],d1[i]));
}
cout<<res<<endl;
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d4fb3c9524092062167dcfae833addbb.png)
3.树的重心
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int h[N],e[N],ne[N],idx=0;
int n;
int ans=N;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dfs(int u,int fa)
{
int sum=1,res=0;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa)continue;
int s=dfs(j,u);
sum+=s;
res=max(s,res);
}
res=max(n-sum,res);
ans=min(ans,res);
return sum;
}
int main()
{
memset(h,-1,sizeof h);
cin>>n;
for(int i=1;i<n;i++)
{
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
dfs(1,-1);
cout<<ans<<endl;
}