📌  相关文章
📜  检查树是否可以拆分为K个相等的连接组件

📅  最后修改于: 2021-04-17 09:52:40             🧑  作者: Mango

给定一棵树和整数K的邻接表表示形式,任务是查找给定的树是否可以分为K个相等的Connected Components。
注意:如果两个连接的组件包含相等数量的节点,则称它们相等。

例子:

方法:
这个想法是在N个节点的给定树上使用深度优先搜索(DFS)遍历,以确定给定树是否可以拆分为K个相等的Connected Components。步骤如下:

  1. 从树的根启动DFS遍历。
  2. 对于在DFS遍历期间未访问的每个顶点,递归调用该顶点的DFS,以在每个DFS递归调用期间保持遍历的节点数。
  3. 如果节点数等于(N / K),则得到一组连接组件中的一个。
  4. 如果( N / K )个节点的连接组件集的总数等于K。然后,可以将给定的图拆分为K个等于Connected Components。

下面是上述方法的实现:

C++
// C++ program to detect whether
// the given Tree can be split
// into K equals components
#include 
using namespace std;
 
// For checking if the graph
// can be split into K equal
// Connected Components
int flag = 0;
 
// DFS Traversal
int DFS(vector adj[], int k,
        int i, int x)
{
 
    // Intialise ans to 1
    int ans = 1;
 
    // Traverse the adjacency
    // for vertex i
    for (auto& it : adj[i]) {
        if (it != k) {
            ans += DFS(adj, i, it, x);
        }
    }
 
    // If number of nodes is
    // greater than x, then
    // the tree cannot be split
    if (ans > x) {
        flag = 1;
        return 0;
    }
 
    // Check for requirement
    // of nodes
    else if (ans == x) {
        ans = 0;
    }
    return ans;
}
 
// A utility function to add
// an edge in an undirected
// Tree
void addEdge(vector adj[],
             int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}
 
// Driver's Code
int main()
{
    int N = 15, K = 5;
 
    // Adjacency List
    vector adj[N + 1];
 
    // Adding edges to List
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 2, 4);
    addEdge(adj, 4, 5);
    addEdge(adj, 5, 6);
    addEdge(adj, 5, 7);
    addEdge(adj, 4, 8);
    addEdge(adj, 4, 9);
    addEdge(adj, 8, 11);
    addEdge(adj, 10, 11);
    addEdge(adj, 11, 14);
    addEdge(adj, 9, 12);
    addEdge(adj, 12, 15);
    addEdge(adj, 12, 13);
 
    // Check if tree can be split
    // into K Connected Components
    // of equal number of nodes
    if (N % K == 0) {
        // DFS call to Check
        // if tree can be split
        DFS(adj, -1, 1, N / K);
    }
 
    // If flag is 0, then the
    // given can be split to
    // Connected Components
    cout << (flag ? "NO" : "YES");
 
    return 0;
}


Java
// Java program to detect whether
// the given Tree can be split
// into K equals components
import java.util.*;
 
class GFG
{
  
// For checking if the graph
// can be split into K equal
// Connected Components
static int flag = 0;
  
// DFS Traversal
static int DFS(Vector adj[], int k,
        int i, int x)
{
  
    // Intialise ans to 1
    int ans = 1;
  
    // Traverse the adjacency
    // for vertex i
    for (int it : adj[i]) {
        if (it != k) {
            ans += DFS(adj, i, it, x);
        }
    }
  
    // If number of nodes is
    // greater than x, then
    // the tree cannot be split
    if (ans > x) {
        flag = 1;
        return 0;
    }
  
    // Check for requirement
    // of nodes
    else if (ans == x) {
        ans = 0;
    }
    return ans;
}
  
// A utility function to add
// an edge in an undirected
// Tree
static void addEdge(Vector adj[],
             int u, int v)
{
    adj[u].add(v);
    adj[v].add(u);
}
  
// Driver's Code
public static void main(String[] args)
{
    int N = 15, K = 5;
  
    // Adjacency List
    Vector []adj = new Vector[N + 1];
    for(int i= 0; i < N + 1; i++)
        adj[i] = new Vector();
     
    // Adding edges to List
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 2, 4);
    addEdge(adj, 4, 5);
    addEdge(adj, 5, 6);
    addEdge(adj, 5, 7);
    addEdge(adj, 4, 8);
    addEdge(adj, 4, 9);
    addEdge(adj, 8, 11);
    addEdge(adj, 10, 11);
    addEdge(adj, 11, 14);
    addEdge(adj, 9, 12);
    addEdge(adj, 12, 15);
    addEdge(adj, 12, 13);
  
    // Check if tree can be split
    // into K Connected Components
    // of equal number of nodes
    if (N % K == 0) {
        // DFS call to Check
        // if tree can be split
        DFS(adj, -1, 1, N / K);
    }
  
    // If flag is 0, then the
    // given can be split to
    // Connected Components
    System.out.print(flag==1 ? "NO" : "YES");
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program to detect whether
# the given Tree can be split
# into K equals components
 
# For checking if the graph
# can be split into K equal
# Connected Components
flag = 0
 
# DFS Traversal
def DFS(adj, k, i, x):
     
    # Intialise ans to 1
    ans = 1
    
    # Traverse the adjacency
    # for vertex i
    for it in adj[i]:
        if it is not k:
            ans += DFS(adj, i, it, x)
             
    # If number of nodes is
    # greater than x, then
    # the tree cannot be split
    if (ans > x):
        flag = 1
        return 0
    
    # Check for requirement
    # of nodes
    elif (ans == x):
        ans = 0
     
    return ans
 
# A utility function to add
# an edge in an undirected
# Tree
def addEdge(adj, u, v):
     
    adj[u].append(v)
    adj[v].append(u)
 
# Driver code
if __name__=="__main__":
     
    (N, K) = (15, 5)
     
    # Adjacency List
    adj = [[] for i in range(N + 1)]
     
    # Adding edges to List
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 2, 4);
    addEdge(adj, 4, 5);
    addEdge(adj, 5, 6);
    addEdge(adj, 5, 7);
    addEdge(adj, 4, 8);
    addEdge(adj, 4, 9);
    addEdge(adj, 8, 11);
    addEdge(adj, 10, 11);
    addEdge(adj, 11, 14);
    addEdge(adj, 9, 12);
    addEdge(adj, 12, 15);
    addEdge(adj, 12, 13);
     
    # Check if tree can be split
    # into K Connected Components
    # of equal number of nodes
    if (N % K == 0):
         
        # DFS call to Check
        # if tree can be split
        DFS(adj, -1, 1, N // K)
    
    # If flag is 0, then the
    # given can be split to
    # Connected Components
    if flag == 1:
        print("NO")
    else:
        print("YES")
 
# This code is contributed by rutvik_56


C#
// C# program to detect whether
// the given Tree can be split
// into K equals components
using System;
using System.Collections.Generic;
 
class GFG
{
   
// For checking if the graph
// can be split into K equal
// Connected Components
static int flag = 0;
   
// DFS Traversal
static int DFS(List []adj, int k,
        int i, int x)
{
   
    // Intialise ans to 1
    int ans = 1;
   
    // Traverse the adjacency
    // for vertex i
    foreach (int it in adj[i]) {
        if (it != k) {
            ans += DFS(adj, i, it, x);
        }
    }
   
    // If number of nodes is
    // greater than x, then
    // the tree cannot be split
    if (ans > x) {
        flag = 1;
        return 0;
    }
   
    // Check for requirement
    // of nodes
    else if (ans == x) {
        ans = 0;
    }
    return ans;
}
   
// A utility function to add
// an edge in an undirected
// Tree
static void addEdge(List []adj,
             int u, int v)
{
    adj[u].Add(v);
    adj[v].Add(u);
}
   
// Driver's Code
public static void Main(String[] args)
{
    int N = 15, K = 5;
   
    // Adjacency List
    List []adj = new List[N + 1];
    for(int i= 0; i < N + 1; i++)
        adj[i] = new List();
      
    // Adding edges to List
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 2, 4);
    addEdge(adj, 4, 5);
    addEdge(adj, 5, 6);
    addEdge(adj, 5, 7);
    addEdge(adj, 4, 8);
    addEdge(adj, 4, 9);
    addEdge(adj, 8, 11);
    addEdge(adj, 10, 11);
    addEdge(adj, 11, 14);
    addEdge(adj, 9, 12);
    addEdge(adj, 12, 15);
    addEdge(adj, 12, 13);
   
    // Check if tree can be split
    // into K Connected Components
    // of equal number of nodes
    if (N % K == 0) {
        // DFS call to Check
        // if tree can be split
        DFS(adj, -1, 1, N / K);
    }
   
    // If flag is 0, then the
    // given can be split to
    // Connected Components
    Console.Write(flag==1 ? "NO" : "YES");
}
}
 
// This code contributed by Rajput-Ji


输出:
YES

时间复杂度: O(V + E),其中V是顶点数,E是边数