📌  相关文章
📜  计算树中的顶点对,使它们之间的距离是偶数

📅  最后修改于: 2022-05-13 01:56:07.407000             🧑  作者: Mango

计算树中的顶点对,使它们之间的距离是偶数

给定一棵N个顶点的树,任务是找到顶点对的数量,使得它们之间的距离是偶数但不能为 0

例子:

朴素方法:朴素方法是尝试所有可能的顶点对,找到它们之间的距离并检查距离是否相等。请按照以下步骤解决问题:

  • 迭代i = 0 到 N-1的所有顶点:
    • j = i+1 迭代到 N-1:
      • 使用DFS查找从ij的距离。
      • 如果距离是偶数,则增加对数。
  • 返回计数。

下面是上述方法的实现。

C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to find the distance
void dfs(int i, int par,
         vector >& adj,
         vector& dis)
{
    // Iterate over all the edges of vertex i
    for (int j : adj[i]) {
 
        // If 'j' is not the parent of 'i'.
        if (j != par) {
 
            // Store the distance
            // from root till 'j'.
            dis[j] = dis[i] + 1;
 
            // Recurse for the child 'j'.
            dfs(j, i, adj, dis);
        }
    }
}
 
// Function to count pairs
int countPairs(int n,
               vector >& edges)
{
    // Stores the final answer.
    int ans = 0;
 
    // Stores the adjacency List of the tree.
    vector > adj(n);
 
    for (int i = 0; i < n - 1; ++i) {
 
        // Add the edge in the adjacency list.
        adj[edges[i][0]].push_back(edges[i][1]);
        adj[edges[i][1]].push_back(edges[i][0]);
    }
 
    // Stores the distance from root till 'i'.
    vector dis(n);
 
    // Iterate over all 'u'
    // of the pair ('u', 'v').
    for (int i = 0; i < n; ++i) {
 
        // Set all the values
        // of 'dis[i]' to '0'.
        fill(dis.begin(), dis.end(), 0);
 
        // Do a dfs with 'i' as
        // the root of the tree.
        dfs(i, -1, adj, dis);
 
        // Iterate over the other end
        // of the pair.
        for (int j = i + 1; j < n; ++j) {
 
            // If the distance is even.
            if (dis[j] % 2 == 0) {
 
                // Increment 'ans' by 1.
                ans++;
            }
        }
    }
 
    // Return the answer 'ans'.
    return ans;
}
 
// Driver Code
int main()
{
    int N = 5;
    vector > edges
        = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    cout << countPairs(N, edges);
    return 0;
}


Javascript


C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Dfs function
void dfs(int i, int par,
         vector >& adj,
         vector& dis)
{
    // Iterate over all edges of vertex 'i'.
    for (int j : adj[i]) {
 
        // If 'j' is not the parent of 'i'.
        if (j != par) {
 
            // Store the distance
            // from root till 'j'.
            dis[j] = dis[i] + 1;
 
            // Recurse for the child 'j'.
            dfs(j, i, adj, dis);
        }
    }
}
 
// Function to count the vertices
int countPairs(int n,
               vector >& edges)
{
    // Stores the adjacency List of the tree.
    vector > adj(n);
    for (int i = 0; i < n - 1; ++i) {
 
        // Add the edge in the adjacency list.
        adj[edges[i][0]].push_back(edges[i][1]);
        adj[edges[i][1]].push_back(edges[i][0]);
    }
 
    // Stores the distance from root till 'i'.
    vector dis(n);
 
    // Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, dis);
 
    // To store the size of set 'L'
    // size of set 'R'.
    int x = 0, y = 0;
 
    // Iterate over all the vertices
    // of the tree.
    for (int i = 0; i < n; ++i) {
 
        // If 'i' is at an even depth.
        if (dis[i] % 2 == 0) {
 
            // Increment the size of set 'L'.
            x++;
        }
        else {
 
            // Increment the size of set 'R'.
            y++;
        }
    }
 
    // Return the answer.
    return x * (x - 1) / 2 + y * (y - 1) / 2;
}
 
// Driver Code
int main()
{
    int N = 5;
    vector > edges
        = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    cout << countPairs(N, edges);
    return 0;
}


Python3
# python3 code to implement the approach
 
# Dfs function
def dfs(i, par, adj, dis):
 
    # Iterate over all edges of vertex 'i'.
    for j in adj[i]:
 
        # If 'j' is not the parent of 'i'.
        if (j != par):
 
            # Store the distance
            # from root till 'j'.
            dis[j] = dis[i] + 1
 
            # Recurse for the child 'j'.
            dfs(j, i, adj, dis)
 
# Function to count the vertices
def countPairs(n, edges):
 
    # Stores the adjacency List of the tree.
    adj = [[] for _ in range(n)]
    for i in range(0, n-1):
 
        # Add the edge in the adjacency list.
        adj[edges[i][0]].append(edges[i][1])
        adj[edges[i][1]].append(edges[i][0])
 
    # Stores the distance from root till 'i'.
    dis = [0 for _ in range(n)]
 
    # Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, dis)
 
    # To store the size of set 'L'
    # size of set 'R'.
    x, y = 0, 0
 
    # Iterate over all the vertices
    # of the tree.
    for i in range(0, n):
 
        # If 'i' is at an even depth.
        if (dis[i] % 2 == 0):
 
            # Increment the size of set 'L'.
            x += 1
 
        else:
 
            # Increment the size of set 'R'.
            y += 1
 
    # Return the answer.
    return x * (x - 1) // 2 + y * (y - 1) // 2
 
 
# Driver Code
if __name__ == "__main__":
 
    N = 5
    edges = [[1, 0], [2, 1], [3, 1], [4, 3]]
 
    # Function call
    print(countPairs(N, edges))
 
# This code is contributed by rakeshsahni


输出
4

时间复杂度:O(N 2 )
辅助空间:O(N)

有效方法:解决问题的有效方法是基于二分图的概念,如下所示。

基于上述观察,很明显对的总数是使用来自同一集合的顶点形成的可能对,即( x C 2 ) + ( y C 2 ) ,其中 [ n C 2 = n * (n – 1)/2,x是集合L的大小,y是集合R]的大小。请按照以下步骤解决问题。

  • 声明并初始化两个变量xy为 0 以存储二分集的大小。
  • 使 root 成为二分集之一的一部分(例如L )。
  • 初始化一个数组(比如dis[] )来存储距离 0 的距离。
  • 从顶点0开始一个 DFS 或 BFS:
    • 在每一时刻,遍历所有的孩子,如果我们还没有访问过这个孩子(假设孩子是j ),那么:
      • 将其距离增加为 dis[current node] = distance[parent] + 1。
      • 如果是偶数,则增加x并使其成为集合 L 的一部分。否则,增加y并使其成为集合 R 的一部分。
    • 递归地对其孩子做同样的事情。
  • 最后,返回x C 2 + y C 2的值。

下面是上述方法的实现。

C++

// C++ code to implement the approach
 
#include 
using namespace std;
 
// Dfs function
void dfs(int i, int par,
         vector >& adj,
         vector& dis)
{
    // Iterate over all edges of vertex 'i'.
    for (int j : adj[i]) {
 
        // If 'j' is not the parent of 'i'.
        if (j != par) {
 
            // Store the distance
            // from root till 'j'.
            dis[j] = dis[i] + 1;
 
            // Recurse for the child 'j'.
            dfs(j, i, adj, dis);
        }
    }
}
 
// Function to count the vertices
int countPairs(int n,
               vector >& edges)
{
    // Stores the adjacency List of the tree.
    vector > adj(n);
    for (int i = 0; i < n - 1; ++i) {
 
        // Add the edge in the adjacency list.
        adj[edges[i][0]].push_back(edges[i][1]);
        adj[edges[i][1]].push_back(edges[i][0]);
    }
 
    // Stores the distance from root till 'i'.
    vector dis(n);
 
    // Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, dis);
 
    // To store the size of set 'L'
    // size of set 'R'.
    int x = 0, y = 0;
 
    // Iterate over all the vertices
    // of the tree.
    for (int i = 0; i < n; ++i) {
 
        // If 'i' is at an even depth.
        if (dis[i] % 2 == 0) {
 
            // Increment the size of set 'L'.
            x++;
        }
        else {
 
            // Increment the size of set 'R'.
            y++;
        }
    }
 
    // Return the answer.
    return x * (x - 1) / 2 + y * (y - 1) / 2;
}
 
// Driver Code
int main()
{
    int N = 5;
    vector > edges
        = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    cout << countPairs(N, edges);
    return 0;
}

Python3

# python3 code to implement the approach
 
# Dfs function
def dfs(i, par, adj, dis):
 
    # Iterate over all edges of vertex 'i'.
    for j in adj[i]:
 
        # If 'j' is not the parent of 'i'.
        if (j != par):
 
            # Store the distance
            # from root till 'j'.
            dis[j] = dis[i] + 1
 
            # Recurse for the child 'j'.
            dfs(j, i, adj, dis)
 
# Function to count the vertices
def countPairs(n, edges):
 
    # Stores the adjacency List of the tree.
    adj = [[] for _ in range(n)]
    for i in range(0, n-1):
 
        # Add the edge in the adjacency list.
        adj[edges[i][0]].append(edges[i][1])
        adj[edges[i][1]].append(edges[i][0])
 
    # Stores the distance from root till 'i'.
    dis = [0 for _ in range(n)]
 
    # Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, dis)
 
    # To store the size of set 'L'
    # size of set 'R'.
    x, y = 0, 0
 
    # Iterate over all the vertices
    # of the tree.
    for i in range(0, n):
 
        # If 'i' is at an even depth.
        if (dis[i] % 2 == 0):
 
            # Increment the size of set 'L'.
            x += 1
 
        else:
 
            # Increment the size of set 'R'.
            y += 1
 
    # Return the answer.
    return x * (x - 1) // 2 + y * (y - 1) // 2
 
 
# Driver Code
if __name__ == "__main__":
 
    N = 5
    edges = [[1, 0], [2, 1], [3, 1], [4, 3]]
 
    # Function call
    print(countPairs(N, edges))
 
# This code is contributed by rakeshsahni
输出
4

时间复杂度:O(N)
辅助空间:O(N)