📌  相关文章
📜  通过以交替方式翻转当前节点子树,最小化将 N-ary Tree 的每个节点从 initial[i] 转换为 final[i] 的操作

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

通过以交替方式翻转当前节点子树,最小化将 N-ary Tree 的每个节点从 initial[i] 转换为 final[i] 的操作

给定一个由 N 个节点组成的N叉树,其值为[0, N – 1]和两个大小为N的二进制数组initial[]final[] ,使得initial[i]表示分配给节点i的值,任务是通过以交替方式翻转节点、其孙子节点等的值直到叶节点来找到将节点的每个值转换为初始[i]最终[i]所需的最小操作数。

例子:

方法:给定的问题可以通过对给定的树执行 DFS 遍历来解决,并以另一种方式更新数组initial[]中节点的值。请按照以下步骤解决此问题:

  • 初始化一个变量,比如total0以存储所需操作的计数。
  • 执行 DFS 遍历,同时跟踪两个布尔变量(最初为false ),这将仅在发生翻转时更改并执行以下步骤:
    • 将当前节点标记为访问节点。
    • 如果当前节点的初始值、当前节点的最终值和当前布尔变量的按位异或的值非零,则翻转当前布尔变量并将总和的值增加1
    • 遍历当前节点所有未访问的子节点,递归调用子节点的DFS Traversal。
  • 完成上述步骤后,打印总计的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include "bits/stdc++.h"
using namespace std;
 
// Function to add an edges in graph
void addEdges(vector adj[],
              int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}
 
// Function to perform the DFS of graph
// recursively from a given vertex u
void DFSUtil(int u, vector adj[],
             vector& visited,
             bool foo, bool foo1,
             int initial[], int final[],
             int& ans)
{
    visited[u] = true;
 
    // Check for the condition for the
    // flipping of node's initial value
    if ((initial[u - 1] ^ foo)
        ^ final[u - 1]
              == true) {
        ans++;
        foo ^= 1;
    }
 
    // Traverse all the children of the
    // current source node u
    for (int i = 0;
         i < adj[u].size(); i++) {
 
        // Swap foo and foo1 signifies
        // there is change of level
        if (visited[adj[u][i]] == false)
 
            DFSUtil(adj[u][i], adj,
                    visited, foo1, foo,
                    initial, final, ans);
    }
}
 
// Function to perform the DFSUtil()
// for all the unvisited vertices
int DFS(vector adj[], int V,
        int initial[], int final[])
{
    int total = 0;
    vector visited(V, false);
 
    // Traverse the given set of nodes
    for (int u = 1; u <= 1; u++) {
 
        // If the current node is
        // unvisited
        if (visited[u] == false)
            DFSUtil(u, adj, visited,
                    0, 0, initial,
                    final, total);
    }
 
    // Print the number of operations
    cout << total;
}
 
// Function to count the number of
// flips required to change initial
// node values to final node value
void countOperations(int N, int initial[],
                     int final[],
                     int Edges[][2])
{
    // Create adjacency list
    vector adj[N + 1];
 
    // Add the given edges
    for (int i = 0; i < N - 1; i++) {
        addEdges(adj, Edges[i][0],
                 Edges[i][1]);
    }
 
    // DFS Traversal
    DFS(adj, N + 1, initial, final);
}
 
// Driver Code
int main()
{
    int N = 3;
    int Edges[][2] = { { 1, 2 }, { 1, 3 } };
    int initial[] = { 1, 1, 0 };
    int final[] = { 0, 1, 1 };
    countOperations(N, initial, final,
                    Edges);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
public class Main
{
    // Create adjacency list
    static int N = 3;
    static Vector> adj = new Vector>();
       
    static Vector visited;
    static int ans;
       
    // Function to add an edges in graph
    static void addEdges(int u, int v)
    {
        adj.get(u).add(v);
        adj.get(v).add(u);
    }
       
    // Function to perform the DFS of graph
    // recursively from a given vertex u
    static void DFSUtil(int u, boolean foo, boolean foo1, boolean[] initial, boolean[] finall)
    {
        visited.set(u, true);
   
        // Check for the condition for the
        // flipping of node's initial value
        if ((initial[u - 1] ^ foo)
            ^ finall[u - 1]
                  == true) {
            ans+=1;
            foo ^= true;
        }
   
        // Traverse all the children of the
        // current source node u
        for (int i = 0;
             i < adj.get(u).size(); i++) {
   
            // Swap foo and foo1 signifies
            // there is change of level
            if (visited.get(adj.get(u).get(i)) == false)
   
                DFSUtil(adj.get(u).get(i), foo1, foo,
                        initial, finall);
        }
    }
       
    // Function to perform the DFSUtil()
    // for all the unvisited vertices
    static void DFS(int V, boolean[] initial, boolean[] finall)
    {
        ans = 0;
        visited = new Vector();
        for(int i = 0; i < V; i++)
        {
            visited.add(false);
        }
   
        // Traverse the given set of nodes
        for (int u = 1; u <= 1; u++) {
   
            // If the current node is
            // unvisited
            if (visited.get(u) == false)
                DFSUtil(u, false, false, initial, finall);
        }
   
        // Print the number of operations
        System.out.print(ans);
    }
       
    // Function to count the number of
    // flips required to change initial
    // node values to final node value
    static void countOperations(int N, boolean[] initial, boolean[] finall, int[][] Edges)
    {
        // Add the given edges
        for (int i = 0; i < N - 1; i++) {
            addEdges(Edges[i][0], Edges[i][1]);
        }
   
        // DFS Traversal
        DFS(N + 1, initial, finall);
    }
     
  // Driver code
    public static void main(String[] args) {
        for(int i = 0; i < N + 1; i++)
        {
            adj.add(new Vector());
        }
        int[][] Edges = { {1, 2}, {1, 3} };
        boolean[] initial = { true, true, false };
        boolean[] finall = { false, true, true};
        countOperations(N, initial, finall, Edges);
    }
}
 
// This code is contributed by divyeshrabadiya07.


Python3
# Python3 program for the above approach
 
# Create adjacency list
N = 3
adj = []
for i in range(N + 1):
    adj.append([])
  
visited = []
ans = 0
  
# Function to add an edges in graph
def addEdges(u, v):
    global adj
    adj[u].append(v)
    adj[v].append(u)
  
# Function to perform the DFS of graph
# recursively from a given vertex u
def DFSUtil(u, foo, foo1, initial, finall):
    global visited, ans, adj
    visited[u] = True
 
    # Check for the condition for the
    # flipping of node's initial value
    if ((initial[u - 1] ^ foo) ^ finall[u - 1] == True):
        ans+=1
        foo ^= True
 
    # Traverse all the children of the
    # current source node u
    for i in range(len(adj[u])):
        # Swap foo and foo1 signifies
        # there is change of level
        if (visited[adj[u][i]] == False):
            DFSUtil(adj[u][i], foo1, foo, initial, finall)
 
# Function to perform the DFSUtil()
# for all the unvisited vertices
def DFS(V, initial, finall):
    global ans, visited
    ans = 0
    visited = [False]*V
 
    # Traverse the given set of nodes
    for u in range(1, 2):
        # If the current node is
        # unvisited
        if (visited[u] == False):
            DFSUtil(u, 0, 0, initial, finall)
 
    # Print the number of operations
    print(ans)
  
# Function to count the number of
# flips required to change initial
# node values to final node value
def countOperations(N, initial, finall, Edges):
    # Add the given edges
    for i in range(N - 1):
        addEdges(Edges[i][0], Edges[i][1])
 
    # DFS Traversal
    DFS(N + 1, initial, finall)
 
Edges = [ [ 1, 2 ], [ 1, 3 ] ]
initial = [ True, True, False ]
finall = [ False, True, True]
countOperations(N, initial, finall, Edges)
 
# This code is contributed by rameshtravel07.


C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
      
    // Create adjacency list
    static int N = 3;
    static List> adj = new List>();
      
    static List visited;
    static int ans;
      
    // Function to add an edges in graph
    static void addEdges(int u, int v)
    {
        adj[u].Add(v);
        adj[v].Add(u);
    }
      
    // Function to perform the DFS of graph
    // recursively from a given vertex u
    static void DFSUtil(int u, bool foo, bool foo1, bool[] initial, bool[] finall)
    {
        visited[u] = true;
  
        // Check for the condition for the
        // flipping of node's initial value
        if ((initial[u - 1] ^ foo)
            ^ finall[u - 1]
                  == true) {
            ans+=1;
            foo ^= true;
        }
  
        // Traverse all the children of the
        // current source node u
        for (int i = 0;
             i < adj[u].Count; i++) {
  
            // Swap foo and foo1 signifies
            // there is change of level
            if (visited[adj[u][i]] == false)
  
                DFSUtil(adj[u][i], foo1, foo,
                        initial, finall);
        }
    }
      
    // Function to perform the DFSUtil()
    // for all the unvisited vertices
    static void DFS(int V, bool[] initial, bool[] finall)
    {
        ans = 0;
        visited = new List();
        for(int i = 0; i < V; i++)
        {
            visited.Add(false);
        }
  
        // Traverse the given set of nodes
        for (int u = 1; u <= 1; u++) {
  
            // If the current node is
            // unvisited
            if (visited[u] == false)
                DFSUtil(u, false, false, initial, finall);
        }
  
        // Print the number of operations
        Console.Write(ans);
    }
      
    // Function to count the number of
    // flips required to change initial
    // node values to final node value
    static void countOperations(int N, bool[] initial, bool[] finall, int[,] Edges)
    {
        // Add the given edges
        for (int i = 0; i < N - 1; i++) {
            addEdges(Edges[i,0], Edges[i,1]);
        }
  
        // DFS Traversal
        DFS(N + 1, initial, finall);
    }
     
  static void Main() {
    for(int i = 0; i < N + 1; i++)
    {
        adj.Add(new List());
    }
    int[,] Edges = { {1, 2}, {1, 3} };
    bool[] initial = { true, true, false };
    bool[] finall = { false, true, true};
    countOperations(N, initial, finall, Edges);
  }
}
 
// This code is contributed by mukesh07.


Javascript


输出:
2

时间复杂度: O(N)
辅助空间: O(N)