让你在一颗树上加1/2条边,从1点开始走,新形成的图每个边经过至少一次需要走几步
(1)如果不能加边,考虑dfs这颗树,很明显是2*(n-1)(每个边都需要走两遍)
(2)如果可以加一条边,加了改边之后形成环,改环上的边只需要走一次即可,贪心的想我们肯定加在直径上
(3)如果可以加两条边,这时候如果加了改边形成的环和上一个环有重叠,为了经过新加的这条边,我们需要把两环重叠的部分再遍历一次(即旧环中的边对新直径的贡献变成-1)。
(4)因为需要获得第一次直径的路径,应该使用两次搜索寻找,这里使用BFS
(5)第二次寻找直径出现负权,需要使用树形DP求直径
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define stop system("pause")
#define sz(x) (int)(x.size())
#define all(x) begin(x),end(x)
#define lla(x) x.rbegin(),x.rend()
using ll = long long;using vi = vector<int>;
#define debug(v) cout<<#v<<":";cout<<v<<endl
using pii = pair<int, int>;const int MX = 1e5 + 10;
#define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(i,b) for(register int i=0,i##len=(int)(b);i< i##len;++i)
#define rpp(i,b) for(register int i=1,i##len=(int)(b);i<=i##len;++i)
template <typename T> istream& operator>>(istream &is,vector<T> &v) {for(auto i = begin(v); i != end(v); i++) is>>*i;return is;}
template <typename T> ostream& operator<<(ostream &os,const vector<T> &v) {for(auto i = begin(v);i!=end(v);i++) os<<*i<<(i==end(v)-1?"\n":" ");return os;}
template<typename T>inline void rd(T &s){s=0;T t=1,k=getchar();for(;k<'0'||k>'9';k=getchar())if (k=='-')t=-1;for(;k>='0'&&k<='9';k=getchar())s=(s<<1)+(s<<3)+(k^48);s*=t;}
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int head[MX],tot;
struct IN{int v,nxt,w;}edge[MX<<1];
void add(int u,int v,int w)
{
edge[tot].v=v;edge[tot].w=w;edge[tot].nxt=head[u];
head[u]=tot++;
}
int n,k,s,e;
int dis[MX],vis[MX];
int fa[MX];//用于找环
void bfs(int st)
{
memset(vis,0,sizeof(vis));
fa[st]=-1;
queue<int>q;
q.push(st);
dis[st]=0,vis[st]=1;
while(q.size())
{
int x=q.front();q.pop();
for(int i=head[x];i!=-1;i=edge[i].nxt)
{
int v=edge[i].v;
if(vis[v]) continue;
fa[v]=i;
dis[v]=dis[x]+edge[i].w,vis[v]=1;
q.push(v);
}
}
s=e=st;
rpp(i,n) if(dis[i]>dis[e]) e=i;
}
int dp[MX],ans;
void dfs(int x,int fx)
{
for(int i=head[x];i!=-1;i=edge[i].nxt)
{
int v=edge[i].v;
if(v==fx) continue;
dfs(v,x);
ans=max(ans,dp[x]+edge[i].w+dp[v]);
dp[x]=max(dp[x],dp[v]+edge[i].w);
}
}
inline int solve()
{
memset(head,-1,sizeof(head));
cin>>n>>k;
rpp(i,n-1)
{
int x,y;cin>>x>>y;
add(x,y,1);add(y,x,1);
}
bfs(1);bfs(e);
if(k==1) return 2*(n-1)-dis[e]+1;
for(int p=e;p!=s;p=edge[fa[p]^1].v)
edge[fa[p]].w=edge[fa[p]^1].w=-1; //依次更改边权
dfs(1,0);
return 2*(n-1)-dis[e]+1-ans+1;
}
signed main()
{
cout<<solve()<<endl;
stop;
return 0;
}