最大化添加的边数以将给定的树转换为二分图
给定一棵有N个节点的树,任务是找到可以添加到树中的最大边数,使其成为二分图。
注意:不允许自循环或多重边缘,但允许循环。
例子:
Input: N = 4, Edges = {{1, 2}, {2, 3}, {1, 4}}
1
/ \
2 4
/
3
Output: 1
Explanation: An edge between nodes 3 and 4 can be added such that the graph still remains bipartite.
No more than 1 edge can be added such that the resultant graph is bipartite.
Input: N = 5, Edges = {{1, 2}, {1, 3}, {2, 4}, {2, 5}}
1
/ \
2 3
/ \
4 5
Output: 2
Explanation: Two edges can be added, (3, 4) and (3, 5) and the graph still remains bipartite.
Naive Approach:解决问题的基本方法如下:
Assign each node of the tree as black or white such that a black node is connected with a white node (There is always such a configuration because a tree is always bipartite).
Then for all possible pair of nodes check if an edge can be added between them.
按照下面提到的步骤来实现上述想法:
- 最初遍历树并将每个节点分配为黑色或白色,以便每条边连接一个黑色和一个白色节点。 (树总是二分的)。
- 遍历所有节点对,并检查是否可以在它们之间添加一条边。
- 如果两个节点的颜色不同,并且它们之间没有边,则可以添加一条边。所以增加计数。
- 否则,不能添加边。
- 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 )
有效的方法:上述方法所花费的时间可以通过使用以下观察来优化:
Say, there were initially B black nodes and W white nodes in the tree. So a bipartite graph made from these nodes can have maximum B*W edges.
Therefore, the maximum number of edges that can be added to the tree with N nodes are B*W – (N-1) [as a tree with N node has N-1 edges]
请按照以下步骤操作:
- 最初遍历树并将每个节点分配为黑色或白色,以便每条边连接一个黑色和一个白色节点。 (树总是二分的)。
- 计算黑色节点和白色节点的数量。
- 使用上面从观察中得出的公式并计算可以添加的最大边数。
下面是上述方法的实现。
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)