• bzoj3124: [Sdoi2013]直径


    第一问应该没人不会吧。

    然后第二问,可以意识(证明也可以)到这些边一定是连续的,我一开始的想法是枚举区间,但是这个是平方级别的不兹瓷

    对于一段区间假如它左右端点查找除直径外最大值的和加上区间的值等于直径,而我对于这个的想法是,这一段的边可能成为答案,但是我没有很好的意识到(lj做题全凭感觉),非这段区间的边必然不能成为答案。这样一个for就可以了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    struct node
    {
        int x,y,next;LL d;
    }a[410000];int len,last[210000];
    void ins(int x,int y,LL d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }//init
    
    
    int L,R;LL mxdis;
    void getL(int x,int fr,LL dis)
    {
        if(dis>mxdis) L=x, mxdis=dis;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr)
                getL(y,x,dis+a[k].d);
        }
    }
    void getR(int x,int fr,LL dis)
    {
        if(dis>mxdis) R=x, mxdis=dis;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr)
                getR(y,x,dis+a[k].d);
        }
    }
    
    //--------------取得树的直径------------------------- 
    
    LL andis;bool v[210000];
    void getfarther(int x,int fr,LL dis)
    {
        if(dis>andis)andis=dis;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr&&v[y]==false)
                getfarther(y,x,dis+a[k].d);
        }
    }
    bool bk;
    int plen,p[210000];LL d[210000];
    void dfs(int x,int fr)
    {
        if(bk==true)return ;
        
        if(x==R)
        {
            bk=true;
            int l=1,r=plen;LL s;
            s=0;
            for(int i=2;i<plen;i++)
            {
                s+=d[i];
                andis=0;getfarther(p[i],0,0);
                if(andis+s==mxdis){r=i;break;}
            }
            s=0;
            for(int i=plen-1;i>=2;i--)
            {
                s+=d[i+1];
                andis=0;getfarther(p[i],0,0);
                if(andis+s==mxdis){l=i;break;}
            }
            if(l>r)l=r;
            printf("%d
    ",r-l);
            return ;
        }
        
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr)
            {
                d[++plen]=a[k].d;
                p[plen]=y;
                v[y]=true;
                dfs(y,x);
                v[y]=false;
                p[plen]=0;
                d[plen--]=0;
            }
        }
    }
    
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("1.out","w",stdout);
        int n,x,y;LL d;
        scanf("%d",&n);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%lld",&x,&y,&d);
            ins(x,y,d);ins(y,x,d);
        }
        mxdis=0;getL(1,0,0);
        mxdis=0;getR(L,0,0);
        printf("%lld
    ",mxdis);
        
        bk=false;
        memset(v,false,sizeof(v));v[L]=true;
        plen=0;p[++plen]=L;
        dfs(L,0);
        return 0;
    }
  • 相关阅读:
    队列分类梳理
    停止线程
    Docker和Kubernetes
    Future、Callback、Promise
    Static、Final、static final
    线程池梳理
    TCP四次挥手
    http1.0、http1.x、http 2和https梳理
    重排序
    java内存模型梳理
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8893666.html
Copyright © 2020-2023  润新知