- 最小值:当任意两两叶子结点的距离都为偶数时 输出1 否则输出3
- 最大值:初始为边的个数n-1 也就是无论树的结构是什么样 一开始我们都默认 边是可以完全不同的 但有些比较特殊的情况 如果存在两个叶子结点 他们距离为2的话 他们必定相同 这时候最大值要-1 假如对于一个父节点 他有x个儿子是叶子 那么这x个儿子的值必定相同 最大值-(x-1)
因为n>=3 必定存在非叶子结点 我们找度不为1的点进行dfs 更好处理最大值 对于有些题还是要敢于猜结论并且去证实 这也是个技巧
具体看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
int cur,d[N],dis[N],h[N],nex[N<<1],to[N<<1];
int ct[2],mx;
void add_edge(int x,int y){
to[++cur]=y;nex[cur]=h[x];h[x]=cur;
}
void dfs(int u,int fa){
if(d[u]==1) ct[dis[u]%2]++;
int cnt = 0;
for(int i = h[u]; i; i = nex[i]){
if(to[i]==fa) continue;
dis[to[i]]=dis[u]+1;
dfs(to[i],u);
if(d[to[i]]==1) cnt++;
}
if(cnt)
mx-=(cnt-1);
}
int main(){
int n;
scanf("%d",&n);
mx = n-1;
for(int i = 1; i <= n-1; i++){
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);add_edge(v,u);
d[u]++,d[v]++;
}
for(int i = 1; i <= n; i++){
if(d[i]!=1){
dfs(i,0);
break;
}
}
int fc = 0;
for(int i = 1; i <= n; i++) if(d[i]==1) fc++;
if(ct[0]==fc||ct[1]==fc) printf("1");
else printf("3");
printf(" %d\n",mx);
return 0;
}