📜  树上的不相交集联合|套装1

📅  最后修改于: 2021-04-24 21:27:50             🧑  作者: Mango

给定一棵树和节点的权重。权重是非负整数。任务是找到给定树的子树的最大大小,以使所有节点的权重相等。
先决条件:不交集集合
例子 :

Input : Number of nodes = 7
        Weights of nodes = 1 2 6 4 2 0 3
        Edges = (1, 2), (1, 3), (2, 4), 
                (2, 5), (4, 6), (6, 7)
Output : Maximum size of the subtree 
with even weighted nodes = 4 
Explanation : 
Subtree of nodes {2, 4, 5, 6} gives the maximum size.

Input : Number of nodes = 6
        Weights of nodes = 2 4 0 2 2 6
        Edges = (1, 2), (2, 3), (3, 4), 
                (4, 5), (1, 6)
Output : Maximum size of the subtree
with even weighted nodes = 6
Explanation : 
The given tree gives the maximum size.

方法:我们只需在树上运行DFS即可找到解决方案。 DFS解决方案在O(n)中给出了答案。但是,我们如何使用DSU解决此问题?我们首先遍历所有边缘。如果两个节点的权重相等,我们将它们合并。答案是具有最大大小的节点集。如果我们将联合查找与路径压缩一起使用,则时间复杂度为O(n)
下面是上述方法的实现:

C++
// CPP code to find maximum subtree such
// that all nodes are even in weight
#include
 
using namespace std;
 
#define N 100010
 
// Structure for Edge
struct Edge
{
    int u, v;
};
 
/*
    'id': stores parent of a node.
    'sz': stores size of a DSU tree.
*/
int id[N], sz[N];
 
// Function to assign root
int Root(int idx)
{
    int i = idx;
     
    while(i != id[i])
        id[i] = id[id[i]], i = id[i];
     
    return i;
}
 
// Function to find Union
void Union(int a, int b)
{
    int i = Root(a), j = Root(b);
     
    if (i != j)
    {
        if(sz[i] >= sz[j])
        {
            id[j] = i, sz[i] += sz[j];
            sz[j] = 0;
        }
        else
        {
            id[i] = j, sz[j] += sz[i];
            sz[i] = 0;
        }
    }
}
 
// Utility function for Union
void UnionUtil(struct Edge e[], int W[], int q)
{
 
    for(int i = 0; i < q; i++)
    {
        // Edge between 'u' and 'v'
        int u, v;
        u = e[i].u, v = e[i].v;
 
        // 0-indexed nodes
        u--, v--;
 
        // If weights of both 'u' and 'v'
        // are even then we make union of them.
        if(W[u] % 2 == 0 && W[v] % 2 == 0)
                    Union(u,v);
    }
}
 
// Function to find maximum
// size of DSU tree
int findMax(int n, int W[])
{
    int maxi = 0;
    for(int i = 1; i <= n; i++)
        if(W[i] % 2 == 0)
            maxi = max(maxi, sz[i]);  
             
    return maxi;
}
 
// Driver code
int main()
{
    /*
        Nodes are 0-indexed in this code
        So we have to make necessary changes
        while taking inputs
    */
 
    // Weights of nodes
    int W[] = {1, 2, 6, 4, 2, 0, 3};
 
    // Number of nodes in a tree
    int n = sizeof(W) / sizeof(W[0]);
 
    // Initializing every node as
    // a tree with single node.
    for(int i = 0; i < n; i++)
            id[i] = i, sz[i] = 1;
 
    Edge e[] = {{1, 2}, {1, 3}, {2, 4},
                {2, 5}, {4, 6}, {6, 7}};
 
    int q = sizeof(e) / sizeof(e[0]);
 
    UnionUtil(e, W, q);
 
    // Find maximum size of DSU tree.
    int maxi = findMax(n, W);
 
    printf("Maximum size of the subtree with ");
    printf("even weighted nodes = %d\n", maxi);
     
    return 0;
}


Java
// Java code to find maximum subtree such
// that all nodes are even in weight
class GFG
{
static int N = 100010;
 
// Structure for Edge
static class Edge
{
    int u, v;
 
    public Edge(int u, int v)
    {
        this.u = u;
        this.v = v;
    }
}
 
/*
'id': stores parent of a node.
'sz': stores size of a DSU tree.
*/
static int []id = new int[N];
static int []sz = new int[N];
 
// Function to assign root
static int Root(int idx)
{
    int i = idx;
     
    while(i != id[i])
    {
        id[i] = id[id[i]];
        i = id[i];
    }
    return i;
}
 
// Function to find Union
static void Union(int a, int b)
{
    int i = Root(a), j = Root(b);
     
    if (i != j)
    {
        if(sz[i] >= sz[j])
        {
            id[j] = i;
            sz[i] += sz[j];
            sz[j] = 0;
        }
        else
        {
            id[i] = j;
            sz[j] += sz[i];
            sz[i] = 0;
        }
    }
}
 
// Utility function for Union
static void UnionUtil(Edge e[], int W[], int q)
{
    for(int i = 0; i < q; i++)
    {
        // Edge between 'u' and 'v'
        int u, v;
        u = e[i].u;
        v = e[i].v;
 
        // 0-indexed nodes
        u--;
        v--;
 
        // If weights of both 'u' and 'v'
        // are even then we make union of them.
        if(W[u] % 2 == 0 && W[v] % 2 == 0)
            Union(u, v);
    }
}
 
// Function to find maximum
// size of DSU tree
static int findMax(int n, int W[])
{
    int maxi = 0;
    for(int i = 1; i < n; i++)
        if(W[i] % 2 == 0)
            maxi = Math.max(maxi, sz[i]);
             
    return maxi;
}
 
// Driver code
public static void main(String[] args)
{
    /*
    Nodes are 0-indexed in this code
    So we have to make necessary changes
    while taking inputs
    */
 
    // Weights of nodes
    int W[] = {1, 2, 6, 4, 2, 0, 3};
 
    // Number of nodes in a tree
    int n = W.length;
 
    // Initializing every node as
    // a tree with single node.
    for(int i = 0; i < n; i++)
    {
        id[i] = i;
        sz[i] = 1;
    }
 
    Edge e[] = {new Edge(1, 2), new Edge(1, 3),
                new Edge(2, 4), new Edge(2, 5),
                new Edge(4, 6), new Edge(6, 7)};
 
    int q = e.length;
 
    UnionUtil(e, W, q);
 
    // Find maximum size of DSU tree.
    int maxi = findMax(n, W);
 
    System.out.printf("Maximum size of the subtree with ");
    System.out.printf("even weighted nodes = %d\n", maxi);
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 code to find maximum subtree such
# that all nodes are even in weight
N = 100010
  
# Structure for Edge
class Edge:
     
    def __init__(self, u, v):
        self.u = u
        self.v = v
     
'''
    'id': stores parent of a node.
    'sz': stores size of a DSU tree.
'''
 
id = [0 for i in range(N)]
sz = [0 for i in range(N)];
  
# Function to assign root
def Root(idx):
 
    i = idx;
      
    while(i != id[i]):
         
        id[i] = id[id[i]]
        i = id[i];
      
    return i;
 
# Function to find Union
def Union(a, b):
 
    i = Root(a)
    j = Root(b);
      
    if (i != j):
     
        if(sz[i] >= sz[j]):
         
            id[j] = i
            sz[i] += sz[j];
            sz[j] = 0;
        else:
         
            id[i] = j
            sz[j] += sz[i];
            sz[i] = 0;
         
# Utility function for Union
def UnionUtil( e, W, q):
     
    for i in range(q):
      
         # Edge between 'u' and 'v'
        u = e[i].u
        v = e[i].v
  
        # 0-indexed nodes
        u -= 1
        v -= 1
  
        # If weights of both 'u' and 'v'
        # are even then we make union of them.
        if(W[u] % 2 == 0 and W[v] % 2 == 0):
            Union(u, v);
     
# Function to find maximum
# size of DSU tree
def findMax(n, W):
 
    maxi = 0
     
    for i in range(1, n):
     
        if(W[i] % 2 == 0):
            maxi = max(maxi, sz[i]);  
              
    return maxi;
 
# Driver code
if __name__=='__main__':
     
    '''
        Nodes are 0-indexed in this code
        So we have to make necessary changes
        while taking inputs
    '''
  
    # Weights of nodes
    W = [1, 2, 6, 4, 2, 0, 3]
  
    # Number of nodes in a tree
    n = len(W)
  
    # Initializing every node as
    # a tree with single node.
    for i in range(n):
     
            id[i] = i
            sz[i] = 1;
  
    e = [Edge(1, 2), Edge(1, 3), Edge(2, 4),
                Edge(2, 5), Edge(4, 6), Edge(6, 7)]
  
    q = len(e)
  
    UnionUtil(e, W, q);
  
    # Find maximum size of DSU tree.
    maxi = findMax(n, W);
  
    print("Maximum size of the subtree with ", end='');
    print("even weighted nodes =", maxi);
      
# This code is contributed by rutvik_56


C#
// C# code to find maximum subtree such
// that all nodes are even in weight
using System;
 
class GFG
{
static int N = 100010;
 
// Structure for Edge
public class Edge
{
    public int u, v;
 
    public Edge(int u, int v)
    {
        this.u = u;
        this.v = v;
    }
}
 
/*
'id': stores parent of a node.
'sz': stores size of a DSU tree.
*/
static int []id = new int[N];
static int []sz = new int[N];
 
// Function to assign root
static int Root(int idx)
{
    int i = idx;
     
    while(i != id[i])
    {
        id[i] = id[id[i]];
        i = id[i];
    }
    return i;
}
 
// Function to find Union
static void Union(int a, int b)
{
    int i = Root(a), j = Root(b);
     
    if (i != j)
    {
        if(sz[i] >= sz[j])
        {
            id[j] = i;
            sz[i] += sz[j];
            sz[j] = 0;
        }
        else
        {
            id[i] = j;
            sz[j] += sz[i];
            sz[i] = 0;
        }
    }
}
 
// Utility function for Union
static void UnionUtil(Edge []e, int []W, int q)
{
    for(int i = 0; i < q; i++)
    {
        // Edge between 'u' and 'v'
        int u, v;
        u = e[i].u;
        v = e[i].v;
 
        // 0-indexed nodes
        u--;
        v--;
 
        // If weights of both 'u' and 'v'
        // are even then we make union of them.
        if(W[u] % 2 == 0 && W[v] % 2 == 0)
            Union(u, v);
    }
}
 
// Function to find maximum
// size of DSU tree
static int findMax(int n, int []W)
{
    int maxi = 0;
    for(int i = 1; i < n; i++)
        if(W[i] % 2 == 0)
            maxi = Math.Max(maxi, sz[i]);
             
    return maxi;
}
 
// Driver code
public static void Main(String[] args)
{
    /*
    Nodes are 0-indexed in this code
    So we have to make necessary changes
    while taking inputs
    */
 
    // Weights of nodes
    int []W = {1, 2, 6, 4, 2, 0, 3};
 
    // Number of nodes in a tree
    int n = W.Length;
 
    // Initializing every node as
    // a tree with single node.
    for(int i = 0; i < n; i++)
    {
        id[i] = i;
        sz[i] = 1;
    }
 
    Edge []e = {new Edge(1, 2), new Edge(1, 3),
                new Edge(2, 4), new Edge(2, 5),
                new Edge(4, 6), new Edge(6, 7)};
 
    int q = e.Length;
 
    UnionUtil(e, W, q);
 
    // Find maximum size of DSU tree.
    int maxi = findMax(n, W);
 
    Console.Write("Maximum size of the subtree with ");
    Console.WriteLine("even weighted nodes = {0}\n", maxi);
}
}
 
// This code is contributed by Princi Singh


输出:
Maximum size of the subtree with even weighted nodes = 4