zoukankan      html  css  js  c++  java
  • luoguP4220 [WC2018]通道 随机化

    有一个非常暴力的做法:枚举 $u,v$ 两点中的一个点作为根,然后在 3 棵树中以这个点为根 DFS 一遍,求最大值.

    然后考虑用随机化去骗分:设当前枚举的点为 $x$,下一个点 $y$ 可以是 $x$ 为根时求出的最优解.

    然后每隔 8 到 9 次随机一个新的 $x$.   

    code: 

    #include <bits/stdc++.h>        
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;
    const int N=200006;   
    int n;  
    struct Graph 
    {      
        ll val[N<<1],dep[N<<1];  
        int hd[N],to[N<<1],nex[N<<1],edges;    
        void add(int u,int v,ll c) 
        {
            nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;  
        }   
        void dfs(int x,int ff) 
        { 
            for(int i=hd[x];i;i=nex[i]) 
            {
                int y=to[i]; 
                if(y==ff) continue;   
                dep[y]=dep[x]+val[i],dfs(y,x);  
            }
        }      
        void DFS(int x) { dep[x]=0,dfs(x,0); }          
    }gr[3];     
    namespace brute
    { 
        int main() 
        {          
            ll ans=0;      
            for(int i=1;i<=n;++i) 
            {
                for(int j=0;j<3;++j)   
                    gr[j].DFS(i);   
                for(int j=1;j<=n;++j)  
                    ans=max(ans,gr[0].dep[j]+gr[1].dep[j]+gr[2].dep[j]);  
            }
            printf("%lld
    ",ans);   
            return 0; 
        }
    };   
    int vis[N];            
    int main() 
    {
        // setIO("input");
        srand(time(NULL));    
    
        scanf("%d",&n);      
        for(int j=0;j<3;++j) 
        {
            for(int i=1;i<n;++i) 
            { 
                ll c; 
                int a,b;  
                scanf("%d%d%lld",&a,&b,&c);   
                gr[j].add(a,b,c);  
                gr[j].add(b,a,c);  
            }
        }   
        int po=rand();   
        ll ans=0;  
        if(n<=5000) brute::main();  
        else 
        {                          
            for(int i=0;i<10;++i) 
            { 
                ll tmp=0; 
                int u=rand()%n+1,id=0;  
                while(vis[u]) u=rand()%n+1;     
                for(int j=0;j<10;++j) 
                {
                    vis[u]=1;      
                    gr[0].DFS(u); 
                    gr[1].DFS(u); 
                    gr[2].DFS(u);             
                    for(int k=1;k<=n;++k) 
                    {
                        if(gr[0].dep[k]+gr[1].dep[k]+gr[2].dep[k]>tmp) 
                        {
                            tmp=gr[0].dep[k]+gr[1].dep[k]+gr[2].dep[k];   
                            id=k;  
                        }    
                    }       
                    ans=max(ans,tmp),u=id; 
                    while(vis[u]) u=rand()%n+1;       
                }
            }
            printf("%lld
    ",ans);  
        }
        return 0; 
    }
    

      

  • 相关阅读:
    在Linux中运行Nancy应用程序
    医疗行业信息化学习资源
    Windows Live Writer 的昨日荣光
    读书笔记:李叔同,说佛(上),为人十训
    使用Expression Tree构建动态LINQ查询
    读书笔记:季羡林关于如何做研究学问的心得
    XML序列化的时候如何支持Namespace
    Kafka Consumer
    Linux环境安装Golang
    Linux 下 zip 文件解压乱码如何解决
  • 原文地址:https://www.cnblogs.com/guangheli/p/12983495.html
Copyright © 2011-2022 走看看