给定一个由N个正整数组成的数组weights [] ,其中weights [i]表示第i个节点的权重,任务是构造一个N元树,以使没有两个直接连接的节点具有相同的权重。如果可以制作这样的树,则将“ Yes”及其边缘打印出来。否则,打印“否” 。
例子:
Input: weights[] = {1 2 1 2 5}
Output:
Yes
1 2
1 4
1 5
2 3
Explanation:
Index: 1 2 3 4 5
Weight : 1 2 1 2 5
The constructed Tree is shown in the following diagram:
Input: weights[] = {1 1 1}
Output: No
Explanation: Since all weights are already same, no such tree can be constructed.
方法:解决此问题的想法是首先检查是否所有节点都被分配了相同的权重。如果发现为真,则无法构造所需的树。否则,可以构造这样的树。因此,遍历数组weights []并检查所有值是否相同。如果发现是真的,则打印“否” 。否则,打印“是”并使用以下步骤构建树:
- 采取任何节点,并使其根节点。
- 现在,将权重不等于根的所有其他节点连接到根节点。现在,其余节点是值等于根节点的节点。
- 选择根节点的任意子节点和所有其余节点连接到它们。因此,在相同权重的节点之间不存在直接边缘。
- 要检查尚未包括哪些节点,请使用辅助数组Visited []跟踪访问的节点。如果访问了某个节点,则将其与该节点相连,但不要将访问节点与另一个节点相连,因为可以将未访问的节点与访问节点相连,反之亦然。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
const int N = 1e5 + 5;
// Keep track of visited nodes
int visited[N];
// Function to construct a tree such
// that there are no two adjacent
// nodes with the same weight
void construct_tree(int weights[], int n)
{
int minimum = *min_element(weights, weights + n);
int maximum = *max_element(weights, weights + n);
// If minimum and maximum
// elements are equal, i.e.
// array contains one distinct element
if (minimum == maximum) {
// Tree cannot be constructed
cout << "No";
return;
}
// Otherwise
else {
// Tree can be constructed
cout << "Yes" << endl;
}
// Find the edges below
// Choose weights[0] as root
int root = weights[0];
// First Node is visited
visited[1] = 1;
// Traverse the array
for (int i = 0; i < n; i++) {
// If current element has the
// same weight as root and if
// the node is visited, then
// do not make an edge
// Otherwise, make an edge
if (weights[i] != root
&& visited[i + 1] == 0) {
cout << 1 << " "
<< i + 1 << " "
<< endl;
// Mark this node as visited
visited[i + 1] = 1;
}
}
// Find a weight not same as the
// root & make edges with that node
int notroot = 0;
for (int i = 0; i < n; i++) {
if (weights[i] != root) {
notroot = i + 1;
break;
}
}
// Join non-roots with remaining nodes
for (int i = 0; i < n; i++) {
// Check if current node's weight
// is same as root node's weight
// and if it is not visited or not
if (weights[i] == root
&& visited[i + 1] == 0) {
cout << notroot << " "
<< i + 1 << endl;
visited[i + 1] = 1;
}
}
}
// Driver Code
int main()
{
int weights[] = { 1, 2, 1, 2, 5 };
int N = sizeof(weights) / sizeof(weights[0]);
// Function Call
construct_tree(weights, N);
}
Java
// Java program for the above approach
import java.lang.*;
import java.io.*;
import java.util.*;
class GFG{
static int N = 100000 + 5;
// Keep track of visited nodes
static int visited[] = new int[N];
// Function to construct a tree such
// that there are no two adjacent
// nodes with the same weight
static void construct_tree(int weights[], int n)
{
int minimum = Arrays.stream(weights).min().getAsInt();
int maximum = Arrays.stream(weights).max().getAsInt();
// If minimum and maximum
// elements are equal, i.e.
// array contains one distinct element
if (minimum == maximum)
{
// Tree cannot be constructed
System.out.println("No");
return;
}
// Otherwise
else
{
// Tree can be constructed
System.out.println("Yes");
}
// Find the edges below
// Choose weights[0] as root
int root = weights[0];
// First Node is visited
visited[1] = 1;
// Traverse the array
for(int i = 0; i < n; i++)
{
// If current element has the
// same weight as root and if
// the node is visited, then
// do not make an edge
// Otherwise, make an edge
if (weights[i] != root &&
visited[i + 1] == 0)
{
System.out.println(1 + " " +
(i + 1) + " ");
// Mark this node as visited
visited[i + 1] = 1;
}
}
// Find a weight not same as the
// root & make edges with that node
int notroot = 0;
for(int i = 0; i < n; i++)
{
if (weights[i] != root)
{
notroot = i + 1;
break;
}
}
// Join non-roots with remaining nodes
for(int i = 0; i < n; i++)
{
// Check if current node's weight
// is same as root node's weight
// and if it is not visited or not
if (weights[i] == root &&
visited[i + 1] == 0)
{
System.out.println(notroot + " " +
(i + 1));
visited[i + 1] = 1;
}
}
}
// Driver Code
public static void main(String[] args)
{
int weights[] = { 1, 2, 1, 2, 5 };
int N = weights.length;
// Function Call
construct_tree(weights, N);
}
}
// This code is contributed by sanjoy_62
Python3
#Python3 program for the above approach
N = 10**5 + 5
#Keep track of visited nodes
visited=[0]*N
#Function to construct a tree such
#that there are no two adjacent
#nodes with the same weight
def construct_tree(weights, n):
minimum = min(weights)
maximum = max(weights)
#If minimum and maximum
#elements are equal, i.e.
#array contains one distinct element
if (minimum == maximum):
#Tree cannot be constructed
print("No")
return
#Otherwise
else:
print("Yes")
#Find the edges below
#Choose weights[0] as root
root = weights[0]
#First Node is visited
visited[1] = 1
#Traverse the array
for i in range(n):
#If current element has the
#same weight as root and if
#the node is visited, then
#do not make an edge
#Otherwise, make an edge
if (weights[i] != root
and visited[i + 1] == 0):
print(1,i+1)
#Mark this node as visited
visited[i + 1] = 1
#Find a weight not same as the
#root & make edges with that node
notroot = 0
for i in range(n):
if (weights[i] != root):
notroot = i + 1
break
#Join non-roots with remaining nodes
for i in range(n):
#Check if current node's weight
#is same as root node's weight
#and if it is not visited or not
if (weights[i] == root
and visited[i + 1] == 0):
print(notroot,i + 1)
visited[i + 1] = 1
#Driver Code
if __name__ == '__main__':
weights=[1, 2, 1, 2, 5]
N = len(weights)
#Function Call
construct_tree(weights, N)
C#
// C# program to implement
// the above approach
using System;
using System.Linq;
class GFG{
static int N = 100000 + 5;
// Keep track of visited nodes
static int[] visited = new int[N];
// Function to construct a tree such
// that there are no two adjacent
// nodes with the same weight
static void construct_tree(int[] weights, int n)
{
int minimum = weights.Min();
int maximum = weights.Max();
// If minimum and maximum
// elements are equal, i.e.
// array contains one distinct element
if (minimum == maximum)
{
// Tree cannot be constructed
Console.WriteLine("No");
return;
}
// Otherwise
else
{
// Tree can be constructed
Console.WriteLine("Yes");
}
// Find the edges below
// Choose weights[0] as root
int root = weights[0];
// First Node is visited
visited[1] = 1;
// Traverse the array
for(int i = 0; i < n; i++)
{
// If current element has the
// same weight as root and if
// the node is visited, then
// do not make an edge
// Otherwise, make an edge
if (weights[i] != root &&
visited[i + 1] == 0)
{
Console.WriteLine(1 + " " + (i + 1) + " ");
// Mark this node as visited
visited[i + 1] = 1;
}
}
// Find a weight not same as the
// root & make edges with that node
int notroot = 0;
for(int i = 0; i < n; i++)
{
if (weights[i] != root)
{
notroot = i + 1;
break;
}
}
// Join non-roots with remaining nodes
for(int i = 0; i < n; i++)
{
// Check if current node's weight
// is same as root node's weight
// and if it is not visited or not
if (weights[i] == root &&
visited[i + 1] == 0)
{
Console.WriteLine(notroot + " " +
(i + 1));
visited[i + 1] = 1;
}
}
}
// Driver Code
public static void Main()
{
int[] weights = { 1, 2, 1, 2, 5 };
int N = weights.Length;
// Function Call
construct_tree(weights, N);
}
}
// This code is contributed by code_hunt.
输出:
Yes
1 2
1 4
1 5
2 3
时间复杂度: O(N)
辅助空间: O(N)