zoukankan      html  css  js  c++  java
  • noip2018 赛道修建

    先放一下代码。题解日后再补。

    怎么说呢,以前老是反感猜结论,其实多猜猜就不会这么想了。

    //80分部分分 乱搞做法
    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> pii;
    #define forg(i,x) for(int i=first[x];i;i=nxt[i])
    #define uu unsigned
    #define fi first
    #define se second
    #define od(x) ((x)&1)
    #define ev(x) (od(x)^1)
    #define mi2(x) (1<<(x))
    #define scanf a1234=scanf
    #define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
    int a1234;
    char buf[1<<18],*bufs=buf,*buft=buf;
    inline int gc(){
        return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
    }
    inline void xxx(){for(;;);}
    
    const int mxn=5e4+3;
    int n,m,to[mxn<<1],nxt[mxn<<1],first[mxn],tot=1,deg[mxn],W[mxn<<1],len[mxn],rt;
    inline int rd(int l,int r){return rand()%(r-l+1)+l;}
    inline void gadd(int x,int y,int l){to[++tot]=y,nxt[tot]=first[x],first[x]=tot,W[tot]=l,++deg[x];}
    struct duru{
        int x,y,l;
    }du[mxn];
    inline void dfs1(int x,int f){
        forg(i,x)if(to[i]!=f)dfs1(to[i],x),len[x]=max(len[x],W[i]+len[to[i]]);
    }
    
    namespace task1{
        int len[mxn],ans=0;
        inline void dfs(int x,int f){
            forg(i,x)if(to[i]!=f)dfs(to[i],x),ans=max(ans,len[x]+len[to[i]]+W[i]),len[x]=max(len[x],W[i]+len[to[i]]);
        }
        int main1(){
            dfs(rt,0);printf("%d
    ",ans);
            return 0;
        }
    }
    int rh[mxn],nn=0;
    inline void getrt(){
        for(int i=1;i<=n;++i)if(deg[i]<=2)rh[++nn]=i;
        rt=rh[rd(1,nn)];
    }
    namespace task2{
        inline bool is(){for(int i=1;i<n;++i)if(du[i].y!=du[i].x+1)return 0;return 1;}
        int w[mxn];
        inline bool can(int x){
            int cnt=0,sum=0;
            for(int i=1;i<n;++i){
                sum+=w[i];
                if(sum>=x)sum=0,++cnt;
            }
            return cnt>=m;
        }
        int main1(){
            for(int i=1;i<n;++i)w[du[i].x]=du[i].l;
            int l=1,r=5e8+11,mid;
            while(l!=r){
                mid=(l+r+1)>>1;
                if(can(mid))l=mid;else r=mid-1;
            }
            printf("%d
    ",l);
            return 0;
        }
    }
    namespace task3{
        inline bool is(){for(int i=1;i<n;++i)if(du[i].x!=1)return 0;return 1;}
        int w[mxn];
        inline bool can(int x){
            int nn=n,cnt=0;
            for(--nn;nn&&w[nn]>=x;--nn)++cnt;
            if(nn==0)return 1;
            int l=1,r=nn;
            while(l<r){
                if(w[l]+w[r]>=x)++cnt,++l,--r;else ++l;
            }
            return cnt>=m;
        }
        int main1(){
            for(int i=1;i<n;++i)w[i]=du[i].l;
            sort(w+1,w+n);
            int l=1,r=5e8+11,mid;
            while(l!=r){
                mid=(l+r+1)>>1;
                if(can(mid))l=mid;else r=mid-1;
            }
            printf("%d
    ",l);
            return 0;
        }
    }
    namespace task4{
        inline bool is(){for(int i=1;i<=n;++i)if(deg[i]>3)return 0;return n<=1000;}
        const int mxn=1003;
        int dp[mxn][2],ls[mxn],rs[mxn],fa[mxn],w[mxn][2],ww[mxn];
        int wan;
        inline void dfs1(int x,int f,int e){
            fa[x]=f,ww[x]=W[e];
            forg(i,x)if(to[i]!=f){
                dfs1(to[i],x,i);
                if(!ls[x])ls[x]=to[i],w[x][0]=W[i];else rs[x]=to[i],w[x][1]=W[i];
            }
        }
        inline void soul(int &f,int x,int sum,int up){
            if(len[x]+sum<wan)return;
            if(sum>=wan)return f=max(f,1+up+dp[x][0]),void();
            if(ls[x])soul(f,ls[x],sum+w[x][0],up+dp[rs[x]][1]);
            if(rs[x])soul(f,rs[x],sum+w[x][1],up+dp[ls[x]][1]);
        }
        inline void sou1(int &f,int x1,int x2,int sum,int up,bool tg){
            if(sum>=wan)return f=max(f,1+up+dp[x2][0]+dp[x1][0]),void();
            if(tg){
                if(sum+len[x2]<wan)return;
                if(ls[x2])sou1(f,x1,ls[x2],sum+w[x2][0],up+dp[rs[x2]][1],1);
                if(rs[x2])sou1(f,x1,rs[x2],sum+w[x2][1],up+dp[ls[x2]][1],1);
            }else{
                if(sum+len[x1]+len[x2]<wan)return;
                sou1(f,x1,x2,sum,up,1);
                if(ls[x1])sou1(f,ls[x1],x2,sum+w[x1][0],up+dp[rs[x1]][1],0);
                if(rs[x1])sou1(f,rs[x1],x2,sum+w[x1][1],up+dp[ls[x1]][1],0);
            }
        }
    
        inline void dfs(int x){
            if(ls[x])dfs(ls[x]);if(rs[x])dfs(rs[x]);
            dp[x][0]=max(dp[ls[x]][0]+dp[rs[x]][1],dp[rs[x]][0]+dp[ls[x]][1]);
            soul(dp[x][0],x,0,0);
            if(ls[x]&&rs[x])sou1(dp[x][0],ls[x],rs[x],w[x][0]+w[x][1],0,0);
            if(x==rt||ww[x]>=wan)return dp[x][1]=dp[x][0]+1,void();
            dp[x][1]=dp[x][0];
            soul(dp[x][1],x,ww[x],0);
        }
        inline bool can(){
            memset(dp,0,sizeof(dp));
            dfs(rt);
            return dp[rt][0]>=m;
        }
        int main1(){
    //    puts("OKKKKKKKKKKKKKKKKK");
            dfs1(rt,0,0);
            int l=1,r=n*10000;
            while(l<r){
                wan=(l+r+1)>>1;
                if(can())l=wan;else r=wan-1;
            }
            printf("%d
    ",l);
            return 0;
        }
    }
    int main(){
        srand((uu)time(0));
        scanf("%d%d",&n,&m);for(int i=1,u,v,l;i<n;++i)scanf("%d%d%d",&u,&v,&l),du[i]=(duru){u,v,l},gadd(u,v,l),gadd(v,u,l);
        getrt();
        dfs1(rt,0);
        if(task4::is())return task4::main1();
    //    puts("ohwwwwwwwwwww");
        if(m==1)return task1::main1();
        if(task2::is())return task2::main1();
        if(task3::is())return task3::main1();
        return 0;
    }
    
    
    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> pii;
    #define forg(i,x) for(int i=first[x];i;i=nxt[i])
    #define uu unsigned
    #define fi first
    #define se second
    #define od(x) ((x)&1)
    #define ev(x) (od(x)^1)
    #define mi2(x) (1<<(x))
    #define scanf a1234=scanf
    #define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
    #define fp fprintf
    int a1234;
    char buf[1<<18],*bufs=buf,*buft=buf;
    inline int gc(){
        return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
    }
    inline void xxx(){for(;;);}
    inline int rd(int l,int r){return rand()%(r-l+1)+l;}
    FILE*fo;
    int tmp[1003];
    inline void dfs(int l,int r){
        if(l==r)return;
        int lc=rd(1,r-l);
        if(lc==r-l)return fp(fo,"%d %d %d
    ",tmp[l],tmp[l+1],rd(1,10000)),dfs(l+1,r);
        dfs(l+1,l+lc),dfs(l+lc+1,r);
        fp(fo,"%d %d %d
    ",tmp[l],tmp[l+1],rd(1,10000)),fp(fo,"%d %d %d
    ",tmp[l],tmp[l+lc+1],rd(1,10000));
    }
    inline void maked(){
        fo=fopen("te.in","w");
        int n=1000,m=rd(1,n-1);
        for(int i=1;i<=n;++i)tmp[i]=i;random_shuffle(tmp+1,tmp+n+1);
        fp(fo,"%d %d
    ",n,m);
        dfs(1,n);
        fclose(fo);
    }
    inline uu work(){
        maked();
        system("./a<te.in>1.ans"),system("./b<te.in>2.ans");
        return system("diff 1.ans 2.ans -b -B -q");
    }
    int main(){
        srand((uu)time(0));
        //return maked(),3;
        system("g++ a.cpp -O2 -Wall -o a"),system("g++ b.cpp -O2 -Wall -o b");
        int cases=0;
        while(1){printf("%d
    ",++cases);if(work())return 222;if(cases==1000)return 0;}
        return 0;
    }
    
    
  • 相关阅读:
    【leetcode】图像渲染
    【leetcode】不邻接植花
    052-75
    052-74
    052-73
    052-71
    052-70
    052-69
    052-67
    052-66
  • 原文地址:https://www.cnblogs.com/happyguy/p/13817519.html
Copyright © 2011-2022 走看看