zoukankan      html  css  js  c++  java
  • BZOJ 1099 树网的核

    题面

    解题思路

    搞了三个多小时。。。。
    noip时的数据很水,直接暴力n^3过。
    我们考虑优化,首先可以贪心,我们要在直径上选肯定越插长越好,所以n^2其实就可以解决。但这还不够,根据直径的最长性,我们可以用一个单调队列优化。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 500005;
    const int inf = 0x7fffffff;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
        return x*f;
    }
    
    int n,s,num,a[MAXN],father[MAXN];
    int head[MAXN],cnt,D,top[MAXN],d[MAXN];
    int to[MAXN<<1],nxt[MAXN<<1],val[MAXN<<1];
    int ans=inf,dis[MAXN],diameter,mx,st,last;
    bool vis[MAXN];
    
    inline void add(int bg,int ed,int v){
        to[++cnt]=ed,val[cnt]=v,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    inline void dfs1(int x,int fa){
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(u==fa) continue;
            dis[u]=max(dis[u],dis[x]+val[i]);
            if(dis[u]>mx){
                mx=dis[u];
                st=u;
            }
            dfs1(u,x);
        }
    }
    
    inline void dfs2(int x,int fa){
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(u==fa) continue;
            father[u]=x;
            dis[u]=max(dis[u],dis[x]+val[i]);
            if(dis[u]>diameter){
                diameter=dis[u];
                last=u;
            }
            dfs2(u,x);
        }
    }
    
    inline void dfs4(int rt,int x,int DIS){
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(vis[u]) continue;
            vis[u]=1;
            if(DIS+val[i]>d[rt])
                d[rt]=DIS+val[i];
            dfs4(rt,u,DIS+val[i]);
            vis[u]=0;
        }
    }
    
    int main(){
        n=rd();s=rd();
        for(register int i=1;i<n;i++){
            int x=rd(),y=rd(),z=rd();
            add(x,y,z);add(y,x,z);
        }
        dfs1(1,0);
        for(register int i=1;i<=n;i++) dis[i]=0;
        dfs2(st,0);
    //  cout<<diameter<<endl; 
        D=diameter;
        mx=0;
        for(register int i=last;i;i=father[i]) {
            top[++num]=i;vis[i]=1;
            a[i]=dis[last]-dis[i];
    //      cout<<a[i]<<endl;
        }
    //  for(register int i=1;i<=num;i++) cout<<a[i]<<endl;
        for(register int i=1;i<=num;i++) dfs4(top[i],top[i],0),mx=max(mx,d[top[i]]);
    //  for(register int i=1;i<=num;i++) cout<<top[i]<<" "<<a[top[i]]<<endl;;
    //  ans=max(d[top[1]],max(a[top[1]],a[top[num]]-a[top[1]]));
        int l=1;
        for(register int i=1;i<=num;i++){
            if(l==num) break;
            while(a[top[l+1]]-a[top[i]]<=s && l<num) l++;
            int now=max(mx,max(a[top[i]],a[top[num]]-a[top[l]]));       
            ans=min(ans,now);
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    研发环境容器化实施过程(docker + docker-compose + jenkins)
    Java虚拟机-字节码执行引擎
    Java虚拟机-类加载机制
    Java虚拟机-字节码指令
    Java虚拟机-类文件结构
    Java虚拟机理解-内存管理
    单元测试实践(SpringCloud+Junit5+Mockito+DataMocker)
    Git基础概念与Flow流程介绍
    谷歌最佳实践
    谷歌最佳实践
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676972.html
Copyright © 2011-2022 走看看