思路差不多是这样子的,k=1 的时候。找到直径,答案就是 2(n−1)−L+1。如果是 k=2 的话,那么原直径边权取 −1 然后再找一次直径,但是看了答案总是差 1 或者差 2 ,不知道为什么会这样。
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
struct eee{
int next;
int to;
int w;
}edge[maxn<<1];
int root[maxn],depth[maxn],fa[maxn],cnt,n,k,max_point;
void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].next=root[x];
edge[cnt].w=1;
root[x]=cnt;
}
void dfs(int u,int p){
fa[u]=p;
for(int i=root[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==p)continue;
depth[v]=depth[u]+edge[i].w;
if(depth[max_point]<depth[v])max_point=v;
dfs(v,u);
}
}
int main(){
freopen("1.in","r",stdin);
cin>>n>>k;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
depth[1]=0;
dfs(1,1);
int top=max_point;
depth[max_point]=0;
//printf("max=%d\n",max_point);
dfs(max_point,max_point);
int length=depth[max_point];
//printf("length=%d\n",length);
int ans=2*(n-1)-length+1;
if(k==2){
while(top!=max_point){
int father=fa[max_point];
for(int i=root[max_point];i;i=edge[i].next){
if(edge[i].to==father){
edge[i].w=-1;
break;
}
}
for(int i=root[father];i;i=edge[i].next){
if(edge[i].to==max_point){
edge[i].w=-1;
break;
}
}
max_point=fa[max_point];
}
depth[1]=0;
dfs(1,1);
depth[max_point]=0;
dfs(max_point,max_point);
ans-=depth[max_point]-1;
}
printf("%d\n",ans);
return 0;
}