zoukankan      html  css  js  c++  java
  • bzoj1999

    这道题真的做得头皮发麻

    题解。。。lyd书上。。。

    头皮发麻

    。。。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int maxn=600000+10;
    const int nil=0x3f3f3f3f;
    
    struct my{
           int next;
           int w;
           int v;
    };
    
    my bian[maxn*2];
    queue<int>Q;
    int adj[maxn],fa,n,pre[maxn],d[maxn],p,path[maxn],top,sum1[maxn],sum2[maxn],q[maxn];
    bool c[maxn];
    
    void myinsert(int u,int v,int w){
         bian[++fa].v=v;
         bian[fa].next=adj[u];
         bian[fa].w=w;
         adj[u]=fa;
    }
    
    int bfs(int x){
        while(!Q.empty()) Q.pop();
        memset(d,0x3f,sizeof(d));
        d[x]=0;
        pre[x]=0;
        Q.push(x);
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            for (int i=adj[u];i;i=bian[i].next){
                    int v=bian[i].v;
                if(d[v]==nil){
                    d[v]=d[u]+bian[i].w;
                    pre[v]=i;
                    Q.push(v);
                }
            }
        }
        int p=1,y=1;
        for (;p<=n;p++) if(d[y]<d[p]) y=p;
        return y;
    }
    
    void dp1(int x,int f){
         for (int i=adj[x];i;i=bian[i].next){
            int v=bian[i].v;
            if(c[v]&&v!=f){
                sum1[v]=sum1[x]+bian[i].w;
                dp1(v,x);
            }
         }
    }
    
    void dp2(int x,int f){
         for (int i=adj[x];i;i=bian[i].next){
            int v=bian[i].v;
            if(c[v]&&v!=f){
                sum2[v]=sum2[x]+bian[i].w;
                dp2(v,x);
            }
         }
    }
    
    void get(){
         p=bfs(1);
         p=bfs(p);
    }
    
    void lu(){
         for (;pre[p];p=bian[pre[p]^1].v) {//可以记录路径,但是一直没搞懂是怎么回事,可能是我太弱吧,记住好了
               // printf("%d %d ",bian[pre[p]].v,bian[pre[p]^1].v);
               if(!c[bian[pre[p]].v]) path[++top]=bian[pre[p]].v;
               if(!c[bian[pre[p]^1].v]) path[++top]=bian[pre[p]^1].v;
                c[bian[pre[p]].v]=true;
                c[bian[pre[p]^1].v]=true;
         }
    }
    
    void dfs(int x){
         c[x]=1;
         for (int i=adj[x];i;i=bian[i].next){
                int v=bian[i].v;
                if(c[v]) continue;
                //printf("%d %d
    ",x,v);
                dfs(v);
                d[x]=max(d[x],d[v]+bian[i].w);
         }
    }
    
    int main(){
        //freopen("1999.in","r",stdin);
       // freopen("1999.out","w",stdout);
        fa=1;
        int u,v,w;
        int s;
        scanf("%d%d",&n,&s);
        for (int i=1;i<n;i++){
            scanf("%d%d%d",&u,&v,&w);
            myinsert(u,v,w);
            myinsert(v,u,w);
        }
        get();
        lu();
        //for (int i=1;i<=top;i++) printf("%d ",path[i]);
        dp1(path[1],path[1]);
        dp2(path[top],path[top]);
        memset(d,0,sizeof(d));
        for (int i=1;i<=top;i++)
                    dfs(path[i]);
        int ans=nil;
        int pp=0;
        for (int i=1;i<=top;i++){
            pp=max(pp,d[path[i]]);
        }
        int ppl=0;
        int i=1,j=1;
        for (;i<=top,j<=top;i++){
            ppl=0;
            while(j<=top&&abs(sum1[path[j]]-sum1[path[i]])<=s) j++;
            ppl=max(ppl,pp);
            ppl=max(ppl,sum1[path[i]]);
            ppl=max(ppl,sum2[path[j]]);
            ans=min(ans,ppl);
        }
        printf("%d
    ",ans);
    return 0;
    }

     还是画图理解一下

    设路径p为最长的不经直径路径,那么p必小于w(u,v),所以v之后路径都比p长

    所以了嘛,答案要么就是p,要么就在直径上

    对,没毛病

    丝毫没毛病

  • 相关阅读:
    好玩的原生js的简单拖拽
    原生js的简单倒计时
    五分钟了解node,cnpm和yarn
    计算水仙花数
    首师大附中科创教育平台 我的刷题记录(1)
    [暑假集训--数位dp]hdu3652 B-number
    [暑假集训--数位dp]hdu2089 不要62
    cf711E ZS and The Birthday Paradox
    Spoj-NETADMIN Smart Network Administrator
    cf449C Jzzhu and Apples
  • 原文地址:https://www.cnblogs.com/lmjer/p/9370801.html
Copyright © 2011-2022 走看看