📌  相关文章
📜  构造一棵树,其所有根到叶路径的节点总和不能被该路径中的节点数整除

📅  最后修改于: 2021-10-25 03:23:09             🧑  作者: Mango

给定一个 N 元树,它由N 个节点组成,节点编号从1 到 N,节点1 为根,任务是为树的每个节点分配值,使得从任何根到叶路径的值之和至少包含两个节点不能被沿该路径的节点数整除。

例子:

方法:可以基于以下观察来解决给定的问题对于节点数至少为 2 的任何根到叶路径,比如K,如果沿该路径的值总和介于K2*K之间,那么该总和永远不能被K整除,因为范围(K, 2*K) 上的任何数字都永远不能被K整除。因此,对于K = 1 ,将奇数级节点的节点值分配为1 ,其余为2 。请按照以下步骤解决问题:

  • 初始化一个数组,比如大小为N + 1 的answer[]来存储分配给节点的值。
  • 初始化一个变量,假设K1来为每个节点赋值。
  • 初始化用于对给定树执行 BFS 遍历的队列,并将值为 1 的节点推送到队列中,并将节点的值初始化为1
  • 迭代直到队列为非空并执行以下步骤:
    • 弹出队列的前节点,如果分配给弹出节点的值为1 ,则将K的值更新为2 。否则,将K更新为1
    • 遍历当前弹出节点的所有子节点,将子节点推入队列,并为子节点赋值K。
  • 完成上述步骤后,打印存储在数组answer[] 中的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include "bits/stdc++.h"
using namespace std;
 
// Function to assign values to nodes
// of the tree s.t. sum of values of
// nodes of path between any 2 nodes
// is not divisible by length of path
void assignValues(int Edges[][2], int n)
{
    // Stores the adjacency list
    vector  tree[n + 1];
     
      // Create a adjacency list
      for(int i = 0; i < n - 1; i++) {
       
      int u = Edges[i][0];
      int v = Edges[i][1];
      tree[u].push_back(v);
      tree[v].push_back(u);
    }
   
    // Stores whether node is
      // visited or not
    vector  visited(n + 1, false);
 
    // Stores the node values
    vector  answer(n + 1);
 
    // Variable used to assign values to
      // the nodes alternatively to the
      // parent child
    int K = 1;
 
    // Declare a queue
    queue  q;
 
    // Push the 1st node
    q.push(1);
 
    // Assign K value to this node
    answer[1] = K;
 
    while (!q.empty()) {
 
        // Dequeue the node
        int node = q.front();
        q.pop();
 
        // Mark it as visited
        visited[node] = true;
 
        // Upgrade the value of K
        K = ((answer[node] == 1) ? 2 : 1);
 
        // Assign K to the child nodes
        for (auto child : tree[node]) {
 
            // If the child is unvisited
            if (!visited[child]) {
 
                // Enqueue the child
                q.push(child);
 
                // Assign K to the child
                answer[child] = K;
            }
        }
    }
     
      // Print the value assigned to
      // the nodes
    for (int i = 1; i <= n; i++) {
        cout << answer[i] << " ";
    }
}
 
// Driver Code
int main()
{
    int N = 11;
    int Edges[][2] = {{1, 2}, {1, 3}, {1, 4},
                      {1, 5}, {2, 6}, {2, 10},
                      {10, 11}, {3, 7}, {4, 8},
                      {5, 9}};
 
    // Function Call
    assignValues(Edges, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to assign values to nodes
// of the tree s.t. sum of values of
// nodes of path between any 2 nodes
// is not divisible by length of path
static void assignValues(int Edges[][], int n)
{
     
    // Stores the adjacency list
    ArrayList> tree = new ArrayList<>();
 
    for(int i = 0; i < n + 1; i++)
        tree.add(new ArrayList<>());
 
    // Create a adjacency list
    for(int i = 0; i < n - 1; i++)
    {
        int u = Edges[i][0];
        int v = Edges[i][1];
        tree.get(u).add(v);
        tree.get(v).add(u);
    }
 
    // Stores whether node is
    // visited or not
    boolean[] visited = new boolean[n + 1];
 
    // Stores the node values
    int[] answer = new int[n + 1];
 
    // Variable used to assign values to
    // the nodes alternatively to the
    // parent child
    int K = 1;
 
    // Declare a queue
    Queue q = new LinkedList<>();
 
    // Push the 1st node
    q.add(1);
 
    // Assign K value to this node
    answer[1] = K;
 
    while (!q.isEmpty())
    {
 
        // Dequeue the node
        int node = q.peek();
        q.poll();
 
        // Mark it as visited
        visited[node] = true;
 
        // Upgrade the value of K
        K = ((answer[node] == 1) ? 2 : 1);
 
        // Assign K to the child nodes
        for(Integer child : tree.get(node))
        {
 
            // If the child is unvisited
            if (!visited[child])
            {
                 
                // Enqueue the child
                q.add(child);
 
                // Assign K to the child
                answer[child] = K;
            }
        }
    }
 
    // Print the value assigned to
    // the nodes
    for(int i = 1; i <= n; i++)
    {
        System.out.print(answer[i] + " ");
    }
}
 
// Driver code
public static void main(String[] args)
{
    int N = 11;
    int Edges[][] = { { 1, 2 }, { 1, 3 }, 
                      { 1, 4 }, { 1, 5 },
                      { 2, 6 }, { 2, 10 },
                      { 10, 11 }, { 3, 7 },
                      { 4, 8 }, { 5, 9 } };
 
    // Function Call
    assignValues(Edges, N);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
from collections import deque
 
# Function to assign values to nodes
# of the tree s.t. sum of values of
# nodes of path between any 2 nodes
# is not divisible by length of path
def assignValues(Edges, n):
   
    # Stores the adjacency list
    tree = [[] for i in range(n + 1)]
 
    # Create a adjacency list
    for i in range(n - 1):
 
        u = Edges[i][0]
        v = Edges[i][1]
        tree[u].append(v)
        tree[v].append(u)
 
    # Stores whether any node is
    # visited or not
    visited = [False]*(n+1)
 
    # Stores the node values
    answer = [0]*(n + 1)
 
    # Variable used to assign values to
    # the nodes alternatively to the
    # parent child
    K = 1
 
    # Declare a queue
    q = deque()
 
    # Push the 1st node
    q.append(1)
 
    # Assign K value to this node
    answer[1] = K
 
    while (len(q) > 0):
 
        # Dequeue the node
        node = q.popleft()
        # q.pop()
 
        # Mark it as visited
        visited[node] = True
 
        # Upgrade the value of K
        K = 2 if (answer[node] == 1) else 1
 
        # Assign K to the child nodes
        for child in tree[node]:
 
            # If the child is unvisited
            if (not visited[child]):
 
                # Enqueue the child
                q.append(child)
 
                # Assign K to the child
                answer[child] = K
 
    # Print the value assigned to
    # the nodes
    for i in range(1, n + 1):
        print(answer[i],end=" ")
 
# Driver Code
if __name__ == '__main__':
    N = 7
    Edges = [ [ 1, 2 ], [ 4, 6 ],
               [ 3, 5 ], [ 1, 4 ],
               [ 7, 5 ], [ 5, 1 ] ]
 
    # Function Call
    assignValues(Edges, N)
 
# This code is contributed by mohit kumar 29.


C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
public class GFG{
 
// Function to assign values to nodes
// of the tree s.t. sum of values of
// nodes of path between any 2 nodes
// is not divisible by length of path
static void assignValues(int[, ] Edges, int n)
{
   
      // Stores the adjacency list
      LinkedList[] tree = new LinkedList[n+1];
 
    for(int i = 0; i < n + 1; i++)
        tree[i] = new LinkedList();
 
    // Create a adjacency list
    for(int i = 0; i < n - 1; i++)
    {
        int u = Edges[i, 0];
        int v = Edges[i, 1];
        tree[u].AddLast(v);
        tree[v].AddLast(u);
    }
 
    // Stores whether node is
    // visited or not
    bool[] visited = new bool[n + 1];
 
    // Stores the node values
    int[] answer = new int[n + 1];
 
    // Variable used to assign values to
    // the nodes alternatively to the
    // parent child
    int K = 1;
 
    // Declare a queue
    Queue q = new Queue();
 
    // Push the 1st node
    q.Enqueue(1);
 
    // Assign K value to this node
    answer[1] = K;
 
    while (q.Count > 0)
    {
 
        // Dequeue the node
        int node = (int)q.Peek();
        q.Dequeue();
 
        // Mark it as visited
        visited[node] = true;
 
        // Upgrade the value of K
        K = ((answer[node] == 1) ? 2 : 1);
 
        // Assign K to the child nodes
        foreach (var child in tree[node])
        {
     
            // If the child is unvisited
            if (!visited[child])
            {
                 
                // Enqueue the child
                q.Enqueue(child);
 
                // Assign K to the child
                answer[child] = K;
            }
        }
    }
 
    // Print the value assigned to
    // the nodes
    for(int i = 1; i <= n; i++)
    {
           Console.Write(answer[i] + " ");
    }
}
 
// Driver code
static public void Main (){
 
    int N = 11;
    int[, ] Edges = { { 1, 2 }, { 1, 3 }, 
                      { 1, 4 }, { 1, 5 },
                      { 2, 6 }, { 2, 10 },
                      { 10, 11 }, { 3, 7 },
                      { 4, 8 }, { 5, 9 } };
 
    // Function Call
    assignValues(Edges, N);
}
}
 
// This code is contributed by Dharanendra L V.


Javascript


输出:
1 2 2 2 2 1 1 1 1 1 2

时间复杂度: O(N),其中 N 是树中节点的总数。
辅助空间: O(N)