城市题解
3s \(O(n^{2})\)过5000怎么也说是没问题的吧,
也并不需要什么信仰,
直接暴力枚举删那条边,然后选择连起来最小的点,跟删后两部分的直径取max就行了。
#include<bits/stdc++.h>
using namespace std;
const int N=5006;
int n,o=0,p,q,w[2],maxt=0,maxp=0,cnt=0,t,head[N],ans=2e9;
struct xd{int a,b,c;}qq[N];
struct edge{int nxt,to,w;}e[N<<1];
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
inline void add(int u,int v,int w){e[++cnt].nxt=head[u],e[cnt].to=v,e[cnt].w=w,head[u]=cnt;}
void dfs(int x,int fa,int y){
for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa&&e[i].to!=t) dfs(e[i].to,x,y+e[i].w);
if(maxt<y) maxt=y,maxp=x;
}
bool dfs2(int x,int fa,int y){
bool flag=0;
for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa&&e[i].to!=t) flag|=dfs2(e[i].to,x,y+e[i].w);
if(maxp==x) flag=1;
if(flag&&w[o]>max(y,maxt-y)) w[o]=max(y,maxt-y);
return flag;
}
int main(){
n=read();
for(int i=1;i<n;++i) qq[i].a=read(),qq[i].b=read(),qq[i].c=read(),add(qq[i].a,qq[i].b,qq[i].c),add(qq[i].b,qq[i].a,qq[i].c);
for(int i=1;i<n;++i){
t=qq[i].b,maxt=maxp=p=q=0,o=0,w[0]=w[1]=2e9;
dfs(qq[i].a,0,0),p=maxp,maxt=maxp=0,dfs(p,0,0),dfs2(p,0,0),q=maxt;
t=qq[i].a,maxt=maxp=0,o=1;
dfs(qq[i].b,0,0),p=maxp,maxt=maxp=0,dfs(p,0,0),dfs2(p,0,0),q=max(maxt,q);
ans=min(ans,max(q,w[0]+w[1]+qq[i].c));
}
printf("%d\n",ans);
return 0;
}