通过以交替方式翻转当前节点子树,最小化将 N-ary Tree 的每个节点从 initial[i] 转换为 final[i] 的操作
给定一个由 N 个节点组成的N叉树,其值为[0, N – 1]和两个大小为N的二进制数组initial[]和final[] ,使得initial[i]表示分配给节点i的值,任务是通过以交替方式翻转节点、其孙子节点等的值直到叶节点来找到将节点的每个值转换为初始[i]到最终[i]所需的最小操作数。
例子:
Input: N = 3, edges = {{1, 2}, {1, 3}}, initial[] = {1, 1, 0}, final[] = {0, 1, 1}
1(1)
/ \
2(1) 3(0)
Output: 2
Explanation:
Operation 1: Pick the node 1 and flips its initial values. After this operation initial[] = {0, 1, 0} and final[] = {0, 1, 1}.
Operation 2: Pick the node 3 and flips its initial values. After this operation initial[] = {0, 1, 1} and final[] = {0, 1, 1}.
Therefore, print 2 as the minimum number of operations.
Input: N = 1, edges = [], initial[] = {0}, final[] = {1}
Output: 1
方法:给定的问题可以通过对给定的树执行 DFS 遍历来解决,并以另一种方式更新数组initial[]中节点的值。请按照以下步骤解决此问题:
- 初始化一个变量,比如total为0以存储所需操作的计数。
- 执行 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)