2322. 从树中删除边的最小分数(异或和&模拟)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2322. 从树中删除边的最小分数(异或和&模拟)相关的知识,希望对你有一定的参考价值。

2322. 从树中删除边的最小分数(异或和&模拟)

预处理子树异或和,

枚举要删的两条边,为方便可以枚举节点,因为每个节点的父边唯一。

但是注意要判断两个节点的关系。

分三种情况:

  • i i i j j j的祖先
  • j j j i i i的祖先
  • i , j i,j i,j非祖先关系。

然后简单异或和算一下,取 m a x max max即可。

class Solution 
public:
    int minimumScore(vector<int> &nums, vector<vector<int>> &edges) 
        int n = nums.size();
        vector<vector<int>> g(n);
        for (auto &e : edges) 
            int x = e[0], y = e[1];
            g[x].push_back(y);
            g[y].push_back(x);
        

        int xr[n], in[n], out[n], clock = 0;
        function<void(int, int)> dfs = [&](int x, int fa) 
            in[x] = ++clock;
            xr[x] = nums[x];
            for (int y : g[x])
                if (y != fa) 
                    dfs(y, x);
                    xr[x] ^= xr[y];
                
            out[x] = clock;
        ;
        dfs(0, -1);

        int ans = INT_MAX;
        for (int i = 2, x, y, z; i < n; ++i)
            for (int j = 1; j < i; ++j) 
                if (in[i] < in[j] && in[j] <= out[i]) x = xr[j], y = xr[i] ^ x, z = xr[0] ^ xr[i]; // i 是 j 的祖先节点
                else if (in[j] < in[i] && in[i] <= out[j]) x = xr[i], y = xr[j] ^ x, z = xr[0] ^ xr[j]; // j 是 i 的祖先节点
                else x = xr[i], y = xr[j], z = xr[0] ^ x ^ y; // 删除的两条边分别属于两颗不相交的子树
                ans = min(ans, max(max(x, y), z) - min(min(x, y), z));
                if (ans == 0) return 0; // 提前退出
            
        return ans;
    
;

以上是关于2322. 从树中删除边的最小分数(异或和&模拟)的主要内容,如果未能解决你的问题,请参考以下文章

hihocoder1860 最大异或和

bzoj3569

从树中删除选定的节点

TreeNode - PrimeNG - 打字稿:如何从树中删除节点?

树上异或和最大

如何从树中删除每个对象[重复]