3s \(O(n^{2})\)過5000怎麼也說是沒問題的吧,不想一想啊,就讓腦子鏽吧
也並不須要什麼信仰,
直接暴力枚舉刪那條邊,而後選擇連起來最小的點,跟刪後兩部分的直徑取max就好了。c++
#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; }