📜  最大化添加的边数以将给定的树转换为二分图

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

最大化添加的边数以将给定的树转换为二分图

给定一棵有N个节点的树,任务是找到可以添加到树中的最大数,使其成为二分图。

注意:不允许自循环或多重边缘,但允许循环。

例子:

Naive Approach:解决问题的基本方法如下:

按照下面提到的步骤来实现上述想法:

  • 最初遍历树并将每个节点分配为黑色或白色,以便每条边连接一个黑色和一个白色节点。 (树总是二分的)。
  • 遍历所有节点对,并检查是否可以在它们之间添加一条边。
    • 如果两个节点的颜色不同,并且它们之间没有边,则可以添加一条边。所以增加计数
    • 否则,不能添加边。
  • count 的最终值就是答案。

下面是上述方法的实现。

C++
// C++ code for the above approach:
  
#include 
using namespace std;
  
// DFS to mark nodes as black or white.
void dfs(int node, int par, bool isBlack,
         vector >& adj,
         vector& color)
{
  
    // Mark color as black or white.
    color[node] = isBlack;
  
    for (int i = 1; i < adj.size(); ++i) {
  
        // If there is no edge,
        // or 'i' is parent, continue.
        if (!adj[node][i] || i == par)
            continue;
  
        dfs(i, node, !isBlack, adj, color);
    }
}
  
// Function to calculate
// maximum number of edges
// that can be added
long long maxEdges(int n,
                   vector > edges)
{
  
    // Build adjacency matrix.
    vector > adj(n + 1,
                              vector(
                                  n + 1, 0));
    for (auto i : edges) {
        adj[i.first][i.second] = 1;
        adj[i.second][i.first] = 1;
    }
  
    // Call DFS to color nodes.
    vector color(n + 1);
    dfs(1, 0, 1, adj, color);
  
    long long ans = 0;
  
    // Iterate over all pairs of nodes.
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
  
            // If the color is different
            // And there is no edge
            // Between them, increment answer.
            if (color[i] != color[j]
                && !adj[i][j])
                ans++;
        }
    }
  
    // Return answer.
    return ans;
}
  
// Driver Code
int main()
{
    int N = 4;
    vector > edges
        = { { 1, 2 }, { 2, 3 }, { 1, 4 } };
    cout << maxEdges(N, edges);
    return 0;
}


C++
// C++ code for the above approach:
  
#include 
using namespace std;
  
// DFS to count number of black nodes.
int dfs(int node, int par, bool isBlack,
        vector >& adj)
{
    int no_Of_Black = isBlack;
    for (int i : adj[node]) {
        if (i == par)
            continue;
  
        // Number of black nodes
        // in each subtree.
        no_Of_Black
            += dfs(i, node, !isBlack, adj);
    }
    return no_Of_Black;
}
  
// Function to find maximum edges
long long maxEdges(int n,
                   vector > edges)
{
  
    // Build adjacency list.
    vector > adj(n + 1);
    for (auto i : edges) {
        adj[i.first].push_back(i.second);
        adj[i.second].push_back(i.first);
    }
  
    // Number of black nodes.
    int no_Of_Black = dfs(1, 0, 1, adj);
  
    // Number of white nodes.
    int no_Of_White = n - no_Of_Black;
  
    // Number of edges that can be added.
    return (1LL * (no_Of_Black)
                * (no_Of_White)
            - (n - 1));
}
  
// Driver code
int main()
{
    int N = 4;
    vector > edges
        = { { 1, 2 }, { 2, 3 }, { 1, 4 } };
    cout << maxEdges(N, edges);
    return 0;
}


输出
1

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

有效的方法:上述方法所花费的时间可以通过使用以下观察来优化:

请按照以下步骤操作:

  • 最初遍历树并将每个节点分配为黑色或白色,以便每条边连接一个黑色和一个白色节点。 (树总是二分的)。
  • 计算黑色节点和白色节点的数量。
  • 使用上面从观察中得出的公式并计算可以添加的最大边数。

下面是上述方法的实现。

C++

// C++ code for the above approach:
  
#include 
using namespace std;
  
// DFS to count number of black nodes.
int dfs(int node, int par, bool isBlack,
        vector >& adj)
{
    int no_Of_Black = isBlack;
    for (int i : adj[node]) {
        if (i == par)
            continue;
  
        // Number of black nodes
        // in each subtree.
        no_Of_Black
            += dfs(i, node, !isBlack, adj);
    }
    return no_Of_Black;
}
  
// Function to find maximum edges
long long maxEdges(int n,
                   vector > edges)
{
  
    // Build adjacency list.
    vector > adj(n + 1);
    for (auto i : edges) {
        adj[i.first].push_back(i.second);
        adj[i.second].push_back(i.first);
    }
  
    // Number of black nodes.
    int no_Of_Black = dfs(1, 0, 1, adj);
  
    // Number of white nodes.
    int no_Of_White = n - no_Of_Black;
  
    // Number of edges that can be added.
    return (1LL * (no_Of_Black)
                * (no_Of_White)
            - (n - 1));
}
  
// Driver code
int main()
{
    int N = 4;
    vector > edges
        = { { 1, 2 }, { 2, 3 }, { 1, 4 } };
    cout << maxEdges(N, edges);
    return 0;
}
输出
1

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