bzoj3124: [Sdoi2013]直径

Posted AKCqhzdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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\n",mxdis);
    
    bk=false;
    memset(v,false,sizeof(v));v[L]=true;
    plen=0;p[++plen]=L;
    dfs(L,0);
    return 0;
}

 

以上是关于bzoj3124: [Sdoi2013]直径的主要内容,如果未能解决你的问题,请参考以下文章

3124: [Sdoi2013]直径

SDOI2013 R1 Day1

bzoj3124 直径 树论

BZOJ3124 直径

BZOJ 3124 直径

bzoj3124