zoukankan      html  css  js  c++  java
  • [WC2018]通道

    题目:洛谷P4220、UOJ#347。

    题目大意:给你三棵树,要你找到两个点,使其在三棵树上的最短路径和最大。

    解题思路:正解是边分治,不会啊。于是本题可以随机化。

    具体是,每次随机一个根,然后暴力找到一个点,该点在三棵树上到根距离和最大。然后以这个点为根继续做,迭代几遍。再重新随机一个根,以此类推(已经求过的根不需要再求)。

    然后卡一下时间,在3000ms左右结束随机,输出答案即可。

    注意当n小于8000时直接暴力,否则随机化可能会死循环。

    于是n大的点,每个点都卡在3000ms左右。

    C++ Code:

    #include<bits/stdc++.h>
    #define N 100005
    #define TIME_LIMIT 2900
    #define CLK (double)clock()/(double)CLOCKS_PER_SEC*1000.0
    #define ll long long
    int n;
    bool ur[N];
    ll ans=0;
    inline int readint(){
        int c=getchar();
        for(;!isdigit(c);c=getchar());
        int d=0;
        for(;isdigit(c);c=getchar())
        d=(d<<3)+(d<<1)+(c^'0');
        return d;
    }
    inline ll debian(){
        int c=getchar();
        for(;!isdigit(c);c=getchar());
        ll d=0;
        for(;isdigit(c);c=getchar())
        d=(d<<3)+(d<<1)+(c^'0');
        return d;
    }
    struct Graph{
        int cnt,head[N];
        ll dis[N];
        struct edge{
            int to,nxt;
            ll dis;
        }e[N<<1];
        inline void addedge(int u,int v,ll w){
            e[++cnt]=(edge){v,head[u],w};
            head[u]=cnt;
            e[++cnt]=(edge){u,head[v],w};
            head[v]=cnt;
        }
        Graph():cnt(0){
            memset(head,0,sizeof head);
        }
        void dfs(int now,int pre){
            for(int i=head[now];i;i=e[i].nxt)
            if(e[i].to!=pre){
                dis[e[i].to]=dis[now]+e[i].dis;
                dfs(e[i].to,now);
            }
        }
    }G[3];
    void not_rand(){
        for(int i=1;i<=n;++i){
            G[0].dis[i]=G[1].dis[i]=G[2].dis[i]=0;
            G[0].dfs(i,0),G[1].dfs(i,0),G[2].dfs(i,0);
            for(int j=1;j<=n;++j){
                ll now=G[0].dis[j]+G[1].dis[j]+G[2].dis[j];
                if(now>ans)ans=now;
            }
        }
        printf("%lld
    ",ans);
    }
    int main(){
        memset(ur,0,sizeof ur);
        srand(20170607);
        n=readint();
        for(int i=1;i<n;++i){
            int u=readint(),v=readint();
            ll w=debian();
            G[0].addedge(u,v,w);
        }
        for(int i=1;i<n;++i){
            int u=readint(),v=readint();
            ll w=debian();
            G[1].addedge(u,v,w);
        }
        for(int i=1;i<n;++i){
            int u=readint(),v=readint();
            ll w=debian();
            G[2].addedge(u,v,w);
        }
        double BEG=CLK;
        if(n<=8000){not_rand();return 0;}
        while(CLK-BEG<=TIME_LIMIT){
            int rt=(ll)rand()*rand()%n+1;
            while(ur[rt]&&CLK-BEG<=TIME_LIMIT)rt=(ll)rand()*rand()%n+1;
            for(int i=1;i<10;++i){
                if(ur[rt])break;
                ur[rt]=1;
                G[0].dis[rt]=G[1].dis[rt]=G[2].dis[rt]=0;
                G[0].dfs(rt,0),G[1].dfs(rt,0),G[2].dfs(rt,0);
                ll mx=0;
                for(int j=1;j<=n;++j){
                    ll now=G[0].dis[j]+G[1].dis[j]+G[2].dis[j];
                    if(now>ans)ans=now;
                    if(!ur[j]&&now>mx){
                        mx=now,rt=j;
                    }
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8652819.html
Copyright © 2011-2022 走看看