在边权都为1的 树上加1条或者2条边(边权为1) ,从1出发遍历所有点,使得总路程最短

 

#include <bits/stdc++.h>
using namespace std ;
 const int N=1e5+2,M=2*N;
 int nxt[M],w[M],go[M],hd[N],all=1;
 int D,d1[N],d2[N],b[N],m,n,id,d[N],ans,pre[N];
 
 void add(int x,int y,int z){
	go[++all]=y,w[all]=z,nxt[all]=hd[x],hd[x]=all;
 }
 void dfs1(int x,int last){
 	int i,y,z;
 	if(d[x]>ans){
 		ans=d[x],id=x;
 	}
 	for(i=hd[x];i;i=nxt[i]){
 		y=go[i],z=w[i]; 
		 if(y!=last){
		 	d[y]=d[x]+z; pre[y]=i; dfs1(y,x);	
		 }
 	}
 }
 void dfs(int x,int last){
 	int i,y,z;
 	for(i=hd[x];i;i=nxt[i]){
 		y=go[i],z=w[i]; 
		if(y!=last){
			dfs(y,x);
			if(d1[x]<d1[y]+z) d2[x]=d1[x],d1[x]=d1[y]+z;
			else if(d2[x]<d1[y]+z) d2[x]=d1[y]+z;
		}
 	}
 	D=max(D,d1[x]+d2[x]);
 }
 signed main(){
 	int i,t,x,y,z;
 	cin>>n>>m;
 	for(i=1;i<n;i++) cin>>x>>y,add(x,y,1),add(y,x,1);
 	dfs1(1,0); t=id;
 	memset(d,0,sizeof(d)),ans=0; dfs1(id,0);
 	
 	if(m==1){
 		cout<<2*(n-1)-ans+1;
 		return 0;
 	}
 	x=id;
 	for(;x!=t;x=go[i^1]){
 		i=pre[x]; w[i]=w[i^1]=-1; 
 	}
 	D=0;
 	dfs(1,0);
 	cout<<n*2-ans-D;
 	return 0;
 }
 
 
 

 

posted on 2023-02-16 21:33  towboat  阅读(18)  评论(0)    收藏  举报