对于一棵树 我们以任一节点为根节点 找到与其相距最远的一个点p1 再以p1为根节点 找到与其相距最远的一个点p2

此时p1到p2的路径就是树的直径 而树的重心(到其他节点的最远距离最小)就在这个直径上

至于为什么..我也不清楚

 

#include <bits/stdc++.h>
using namespace std;
#define ll long long

struct node1
{
int u;
int v;
ll w;
};

struct node2
{
int v;
ll w;
int next;
};

node1 edge1[200010];
node2 edge2[100010];
int f[100010],first[100010],book[100010],core[100010];
ll ans1,ans2,maxx,dia;
int n,m,num,p1,p2,tar;

int cmp(node1 n1,node1 n2);
void addedge(int u,int v,ll w);
int unite(int u,int v);
int getf(int p);
void dfs1(int cur,ll dis);
int dfs2(int cur);
void dfs3(int cur,ll dis);

int main()
{
int i,j,cnt;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=m;i++)
{
scanf("%d%d%lld",&edge1[i].u,&edge1[i].v,&edge1[i].w);
}
sort(edge1+1,edge1+m+1,cmp);
for(i=1;i<=n;i++)
{
f[i]=i;
}
memset(first,-1,sizeof(first));
num=0,ans1=0,cnt=0;
for(i=1;i<=m;i++)
{
if(unite(edge1[i].u,edge1[i].v))
{
addedge(edge1[i].u,edge1[i].v,edge1[i].w);
addedge(edge1[i].v,edge1[i].u,edge1[i].w);
ans1+=edge1[i].w;
cnt++;
}
if(cnt==n-1) break;
}

memset(book,0,sizeof(book));
book[1]=1;
maxx=0;
dfs1(1,0);
p1=p2;
memset(book,0,sizeof(book));
book[p2]=1;
maxx=0;
dfs1(p2,0);

memset(book,0,sizeof(book));
memset(core,0,sizeof(core));
book[p1]=1;
core[p1]=1;
dia=0;
dfs2(p1);

dfs3(p1,0);

if(ans2<dia/2) ans2=dia-ans2;
printf("%lld\n%lld\n",ans1,ans2);
}
return 0;
}

int cmp(node1 n1,node1 n2)
{
return n1.w<n2.w;
}

void addedge(int u,int v,ll w)
{
edge2[num].v=v;
edge2[num].w=w;
edge2[num].next=first[u];
first[u]=num++;
return;
}

int unite(int u,int v)
{
int fu,fv;
fu=getf(u);
fv=getf(v);
if(fu!=fv)
{
f[fv]=fu;
return 1;
}
else
{
return 0;
}
}

int getf(int p)
{
if(f[p]==p) return f[p];
else
{
f[p]=getf(f[p]);
return f[p];
}
}

void dfs1(int cur,ll dis)
{
ll w;
int i,v;
if(dis>maxx)
{
maxx=dis;
p2=cur;
}
for(i=first[cur];i!=-1;i=edge2[i].next)
{
v=edge2[i].v,w=edge2[i].w;
if(book[v]==0)
{
book[v]=1;
dfs1(v,dis+w);
}
}
return;
}

int dfs2(int cur)
{
ll w;
int i,v,flag;
if(cur==p2) return 1;
flag=0;
for(i=first[cur];i!=-1;i=edge2[i].next)
{
v=edge2[i].v,w=edge2[i].w;
if(book[v]==0)
{
book[v]=1;
flag=dfs2(v);
}
if(flag==1)
{
core[v]=1;
dia+=w;
return 1;
}
}
return 0;
}

void dfs3(int cur,ll dis)
{
ll w;
int i,v;
for(i=first[cur];i!=-1;i=edge2[i].next)
{
v=edge2[i].v,w=edge2[i].w;
if(core[v]==1)
{
core[v]=0;
if((fabs(dia/2-dis))<(fabs(dia/2-dis-w)))
{
ans2=dis;
return;
}
dfs3(v,dis+w);
}
}
return;
}