都算是板子吧
树的重心
//重心:如果该点删除后,剩余连通块点数最大值最小
vector<int> aa[100005];
int n , ans = 1e9;
int dfs(int u,int fa){
int sum = 1 , size = 0;//sum表示所有结点数 size表示u孩子的最大点数
for( auto v : aa[u]){
if(v != fa){
int t = dfs(v , u);
sum += t;
size = max(size , t);
}
}
size = max(size , n-sum);//连通块点数最大值
ans = min(ans , size);//最小
return sum;
}
int main( ){
cin>>n;
for(int i=1;i<n;i++){
int x,y;cin>>x>>y;
aa[x].push_back(y);
aa[y].push_back(x);
}
dfs(1,0);
cout<<ans<<endl;
}
树的直径(大臣的旅费)
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false) , cin.tie(0) ;
#define ll long long
using namespace std ;
const int N = 1e5+5;
bool vis[N];
int n , ans = 0;
int h[N],e[N*2],w[N*2],ne[N*2],idx;
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){
vis[u] = 1;
int max1 = 0,max2 = 0;
for(int i=h[u] ; i != -1 ; i=ne[i]){
int j = e[i];
if(vis[j]) continue;
int d = dfs(j) + w[i];
if(d > max1) max2 = max1 , max1 = d;
else if(d > max2) max2 = d;
}
ans = max(ans , max1+max2);
return max1;
}
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(1);
ll sum = 0;
for(int i=1;i<=ans;i++)
sum += 10 + i;
cout<<sum<<endl;
}