zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    iOS跳转系统设置界面
    Swift中GCD与NSOperation相关
    将某字段按逗号分隔展示
    Java参考资料
    iOS消息推送相关
    [转]8 Regular Expressions You Should Know
    Oracle表锁住处理
    iframe自适应高度处理方案
    Mac常用软件推荐
    java代码块
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8893666.html
Copyright © 2011-2022 走看看