📜  删除最多 P 条边后检查每个连接组件的 XOR 是否相等

📅  最后修改于: 2022-05-13 01:56:12.832000             🧑  作者: Mango

删除最多 P 条边后检查每个连接组件的 XOR 是否相等

给定一棵具有N个节点和一个整数P的树,任务是删除范围 [1, P) 内的边,并为形成的每个连接组件找到节点的 XOR。如果节点的值对于所有形成的连接组件都相等,则打印“YES”否则“NO”。

例子:

方法:解决此问题的方法基于以下观察:

请按照以下步骤应用上述方法:

要找到这样的子树,至少有 3 个连接的组件,可以使用 DFS 遍历轻松完成,并且在回溯期间,我们将在每次迭代时存储每个索引 XOR。

下面是上述方法的实现:

C++
// C++ code for Check after removing
// edges bitwise XOR of each connected
// component formed is equal
 
#include 
using namespace std;
 
const int N = 1e5;
 
// adjacency list to form a tree
vector adj[N];
 
// array arr defined to store node values
// array cal_XOR defined to store
// xor values rooted at i'th level
int nodes[N], cal_XOR[N];
 
// defined a visited array
vector visited(N);
 
// defined a counter to store
// number of subtrees having value equal
// to whole tree XOR
int counter = 0;
 
// first dfs function to find
// xor of subtrees
int dfs_First(int x)
{
    // initializing cal_XOR
    // array with tree node's value
    cal_XOR[x] = nodes[x];
 
    // marking each visited node as true
    visited[x] = true;
 
    // iterating through current node children
    for (auto y : adj[x]) {
        // check if node->child is not visited
        if (!visited[y]) {
            // computing xor of subtree rooted at x
            cal_XOR[x] ^= dfs_First(y);
        }
    }
 
    // returning xor of subtree rooted at x
    return cal_XOR[x];
}
 
// second dfs function to count
// subtrees having values equal
// to entire XOR of tree nodes values
// and returning subtree XOR till that point
int dfs_Second(int x)
{
 
    // marking each visited node as true
    visited[x] = true;
 
    // storing value of nodes[x]
    // to another variable temp
    // for further calculation
    int temp = nodes[x];
 
    // iterating through current node children
    for (auto y : adj[x]) {
 
        // check if node->child is not visited
        if (!visited[y]) {
 
            // storing xor of subtree
            temp ^= dfs_Second(y);
        }
    }
 
    // now, checking if xor of subtree
    // computed till now is equal to
    // entire XOR of tree (root)
    // i.e. value at cal_XOR[0] ->
    // which will give entire XOR of the tree
    if (temp == cal_XOR[0]) {
        // then, make that xor 0
        temp = 0;
 
        // increase count by 1, which
        // means we found a subtree
        counter++;
    }
 
    // return xor of subtree
    // till that point
    return temp;
}
// Function to add edges
void addEdge(int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}
// Function to take input
// for (n-1) edges
void init(int edges[4][2], int numEdges)
{
    for (int i = 0; i < numEdges; i++) {
        edges[i][0]--;
        edges[i][1]--;
        addEdge(edges[i][0], edges[i][1]);
    }
}
 
// Driver Code
int main()
{
 
    // taking input
    int n = 5, p = 2;
    nodes[0] = 1, nodes[1] = 6, nodes[2] = 4,
    nodes[3] = 1, nodes[4] = 2;
 
    // making our visited array false
    for (int i = 0; i < n; i++) {
        visited[i] = false;
    }
 
    // taking input for (n-1) edges
    int edges[4][2]
        = { { 1, 2 }, { 2, 3 }, { 1, 4 }, { 4, 5 } };
    init(edges, 4);
 
    // First dfs Function call
    dfs_First(0);
 
    // again, marking visited array to false
    for (int i = 0; i < n; i++) {
        visited[i] = false;
    }
 
    // initializing answer variable
    bool answer = false;
 
    // if we found XOR of entire tree
    // equal to zero, answer = "YES", as
    // it means there are two connected
    // components equal to each other
    // thus, a single edge can be removed
    if (cal_XOR[0] == 0) {
        answer = true;
    }
    else {
        // second DFS function call
        dfs_Second(0);
 
        // if we found 2 subtree having
        // equal value with XOR of entire tree
        // answer is always "YES", such that
        // p > 2
        if (counter >= 2 and p != 2) {
            answer = true;
        }
    }
    // printing the final answer
    if (answer == true) {
        cout << "YES"
             << "\n";
    }
    else {
        cout << "NO"
             << "\n";
    }
 
    // making counter = 0 for next iteration
    counter = 0;
 
    for (int i = 0; i < n; i++) {
 
        // similarly clearing adjacency list
        // and both arr and cal_XOR array
        adj[i].clear();
        cal_XOR[i] = nodes[i] = 0;
    }
}


Javascript


输出
YES

时间复杂度: O(N+E),其中 N= 节点数,E = 边数
辅助空间: O(N+E),其中 N= 节点数,E = 边数