思路大致是这样的,对于k$$=$$1的情况直接找出链然后 n$$*$$2$$-$$1$$-$$树的直径 就可以了。
对于k$$=$$2的情况。找一遍链上的点,然后找不属于链上的个节点的剩余链的长度中取最长的然后一减(n$$*$$2$$-$$树的直径$$-$$剩余最长链)就完事了。
以下是最后的代码:
#include<bits/stdc++.h>
using namespace std;
int n,k,maxx[100010],maxx2[100010],maxxx,maxxxx,to1[100010],to2[100010],start;
vector<int>e[100010];
bool v[100010],huan[100010];
void maxlen(int x){
v[x]=true;
for(int p:e[x]){
if(v[p])continue;
maxlen(p);
if(maxx[p]+1>maxx[x]){
to2[x]=to1[x];
maxx2[x]=maxx[x];
to1[x]=p;
maxx[x]=maxx[p]+1;
}else if(maxx[p]+1>maxx2[x]){
to2[x]=p;
maxx2[x]=maxx[p]+1;
}
}
if(maxxx<max(maxx[x],0)+max(maxx2[x],0)){
maxxx=max(maxx[x],0)+max(maxx2[x],0);
start=x;
}
return;
}
void find(int x){
if(x==-1)return;
huan[x]=true;
find(to1[x]);
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)to1[i]=-1,to2[i]=-1;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
e[x].push_back(y);
e[y].push_back(x);
}
maxlen(1);
if(k==1){
cout<<2*n-1-maxxx<<endl;
return 0;
}
find(to1[start]);
find(to2[start]);
for(int i=1;i<=n;i++){
if(huan[i]){
if(i==start){
for(int p:e[i]){
if(p==to1[i]||p==to2[i])continue;
if(maxx[i]!=0)maxxxx=max(maxxxx,maxx[p]+1);
}
}else{
if(maxx2[i]!=0)maxxxx=max(maxxxx,maxx2[i]+1);
}
}
}
cout<<2*n-maxxx-maxxxx<<endl;
return 0;
}