• 2020牛客暑期多校训练营(第五场) Graph


    本题和cf 888G是一样的

    利用分治算法

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    const int maxn = 2e5+11;
    typedef long long ll;
    
    ll list[maxn];
    ll tree[maxn*33][3];
    
    int cnt=0;
    
    ll add(ll x){//把数值插入字典树
        int root = 0;
        for(int i=29;i>=0;i--){
            int t = (x>>i)&1;
            if(!tree[root][t]) tree[root][t] = ++cnt;
            root = tree[root][t];//向下爬
        }
        return 0;
    }
    
    ll find(ll x){//查找字典树里面和x异或最小的数值
        int root = 0;
        ll an =0 ;
        for(int i= 29;i>=0;i--){
            ll t = (x>>i)&1;
            if(tree[root][t]) root = tree[root][t];
            else{
                root = tree[root][t^1];
                an |= (1<<i);
            }
        }
        return an;
    }
    
    ll ans = 0;
    
    int dfs(int l,int r,int dep){
        if(dep==-1||l>=r) return 0;
    
        int mid = -100;
        for(int i = l;i<=r;i++){
            if((list[i]>>dep)&1) break;
            mid = i;
        }
    
        if(mid == -100 || mid == r){//全是1
            dfs(l,r,dep-1);
        }
        else{
            dfs(l,mid,dep-1);
            dfs(mid+1,r,dep-1);
        }
    
        if(mid==-100||mid==r) return 0;//dep位置全是0 或者全是1
    
        for(int i = l;i<=mid;i++){
            add(list[i]);
        }
    
    
        long long cns = 1e15;
    
        for(int i = mid+1;i<=r;i++){
            long long a = find(list[i]);
            cns = min(cns,a);
        }
    
        ans += 1LL*cns;
        
        for(int i=0;i<=cnt;i++){
            tree[i][0] = tree[i][1] = 0;
        }
        cnt = 0;
        return 0;
    }
    struct Node{
        int p;
        int len;
        Node(int aa,int bb):p(aa),len(bb){}
    };
    
    vector<Node>G[maxn];
    void add(int x,int y,int len){
        G[x].push_back(Node(y,len));
    }
    int dfs2(int x,int fa,int dep){
        list[x] = dep;
        for(int i=0;i<G[x].size();i++){
            int p = G[x][i].p;
            int ln = G[x][i].len;
            if(p == fa) continue;
            dfs2(p,x,(dep^ln));
        }
        return 0;
    }
    
    int main(){
        ios::sync_with_stdio(false);
        int n;
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int x,y,len;
            scanf("%d%d%d",&x,&y,&len);
            x++;
            y++;
            add(x,y,len);
            add(y,x,len);
        }
        dfs2(1,-1,0);
        sort(list+1,list+1+n);
        ans = 0;
        dfs(1,n,29);
        printf("%lld
    ",ans);
        return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    idea安装好python后显示无SDK问题
    使用idea在windows上连接远程hadoop开发_配置环境
    最小二乘法估计----MATLAB最小二乘法求一元线性回归
    MATLAB最小二乘法求线性回归
    MATLAB求解线性规划(含整数规划和0-1规划)问题
    蒙特卡洛方法蒙特卡洛方法 matlab 实现 matlab 实现
    MATLAB神经网络实例及训练结果各参数解释
    单元格添加斜线
    ppt的高级设计法——虚实结合
    word中插入六角括号的方法﹝﹞
  • 原文地址:https://www.cnblogs.com/lesning/p/13411295.html
Copyright © 2020-2023  润新知