城市题解

城市题解

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;
}
posted @ 2019-10-20 19:13  lsoi_ljk123  阅读(107)  评论(0编辑  收藏  举报