• bzoj2599: [IOI2011]Race


    就和上一题差不多嗟

    波老师说nlogn^2跑的过去,我想着还是优越点写个nlogn吧

    用开1000000个vector记录下边权和为d的方案

    然后出来一个个匹配就好啦~

    然鹅。。。。

    bzoj跑不过去,luogu开O2跑得贼快,CH也过了


    ORZ肉老师,不用把全部记录的,就把边权和为d的方案中,属于不同子树的最小值和次小值记下来就行了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,K;
    struct node
    {
        int x,y,d,next;
    }a[410000];int len,last[210000];
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    
    int rt,sum,tot[210000],G[210000];
    bool v[210000];
    void getrt(int x,int fr)
    {
        G[x]=0;tot[x]=1;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr&&v[y]==false)
            {
                getrt(y,x);
                G[x]=max(G[x],tot[y]);
                tot[x]+=tot[y];
            }
        }
        G[x]=max(G[x],sum-tot[x]);
        if(rt==0||G[rt]>G[x])rt=x;
    }
    
    //--------------------------
    
    struct zz
    {
        int bel,d,ad;
        zz(){}
        void init(){bel=-1;ad=2147483647;}
    }z[210000];int zlen;
    zz vec[1000010][2]; int tim,ti[1000010];
    void vecpush(int d)
    {
        if(vec[d][0].ad>z[zlen].ad)
        {
            zz t=vec[d][0];
            vec[d][0]=z[zlen];
            if(vec[d][0].bel!=t.bel)vec[d][1]=t;
        }
        else if(vec[d][1].ad>z[zlen].ad&&z[zlen].bel!=vec[d][0].bel)
            vec[d][1]=z[zlen];
    }
    void getd(int x,int fr,int bel,int d,int dep)
    {
        if(d>K)return ;
        zlen++;
        z[zlen].bel=bel;z[zlen].d=d;z[zlen].ad=dep;
        
        if(ti[d]!=tim)
        {
            ti[d]=tim;
            vec[d][0].init(),vec[d][1].init();
        }
        vecpush(d);
        
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr&&v[y]==false)getd(y,x,bel,d+a[k].d,dep+1);
        }
    }
    int mmin;
    void calc(int x)
    {
        zlen=0; tim++;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(v[y]==false)getd(y,x,y,a[k].d,1);
        }
        for(int i=1;i<=zlen;i++)
        {
            int j=K-z[i].d;
            if(z[i].d<=K/2&&ti[j]==tim)
            {
                if(z[i].bel!=vec[j][0].bel&&vec[j][0].bel!=-1)mmin=min(mmin,z[i].ad+vec[j][0].ad);
                else if(vec[j][1].bel!=-1)mmin=min(mmin,z[i].ad+vec[j][1].ad);
            }
            if(z[i].d==K)mmin=min(mmin,z[i].ad);
        }
    }
    
    //---------------------------
    
    void divi(int x)
    {
        v[x]=true;calc(x);
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(v[y]==false)
            {
                rt=0;sum=tot[y];
                getrt(y,x);
                divi(rt);
            }
        }
    }
    
    
    int main()
    {
        freopen("race.in","r",stdin);
        freopen("race.out","w",stdout);
        scanf("%d%d",&n,&K);
        len=0;memset(last,0,sizeof(last));
        int x,y,d;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&d);x++;y++;
            ins(x,y,d);ins(y,x,d);
        }
        rt=0;sum=n;
        memset(v,false,sizeof(v));
        getrt(1,0);
        
        mmin=2147483647;tim=0;
        divi(rt);
        if(mmin==2147483647)printf("-1
    ");
        else printf("%d
    ",mmin);
        
        return 0;
    }
  • 相关阅读:
    模态框 显示出模态框后在加载(可用模块框中加入editormd编辑器)
    python实现 列表内元素按照出现次数排序
    Selenium
    Python的Tqdm模块——进度条配置
    [Python3]selenium爬取淘宝商品信息
    如何用Matplotlib画一张好看的图
    maven如何引入本地jar
    tensorflow和bazel版本对应问题及对应的bazel安装
    tensorflow保存模型的3种方式的资源汇总
    利用率统计脚本
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9447846.html
Copyright © 2020-2023  润新知