2493. Divide Nodes Into the Maximum Number of Groups #1246
-
Topics: You are given a positive integer You are also given a 2D integer array Divide the nodes of the graph into
Return the maximum number of groups (i.e., maximum Example 1:
Example 2:
Constraints:
Hint:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
The problem, "Divide Nodes Into the Maximum Number of Groups", involves determining the maximum number of groups into which the nodes of an undirected graph can be divided, such that:
Key Points
Approach
Plan
Let's implement this solution in PHP: 2493. Divide Nodes Into the Maximum Number of Groups <?php
/**
* @param Integer $n
* @param Integer[][] $edges
* @return Integer
*/
function magnificentSets($n, $edges) {
$graph = array_fill(0, $n, []);
$uf = new UnionFind($n);
$rootToGroupSize = [];
foreach ($edges as $edge) {
$u = $edge[0] - 1;
$v = $edge[1] - 1;
$graph[$u][] = $v;
$graph[$v][] = $u;
$uf->unionByRank($u, $v);
}
for ($i = 0; $i < $n; $i++) {
$newGroupSize = $this->bfs($graph, $i);
if ($newGroupSize == -1) {
return -1;
}
$root = $uf->find($i);
if (!isset($rootToGroupSize[$root])) {
$rootToGroupSize[$root] = 0;
}
$rootToGroupSize[$root] = max($rootToGroupSize[$root], $newGroupSize);
}
$ans = 0;
foreach ($rootToGroupSize as $groupSize) {
$ans += $groupSize;
}
return $ans;
}
/**
* @param $graph
* @param $u
* @return int
*/
private function bfs($graph, $u) {
$step = 0;
$queue = [$u];
$nodeToStep = [$u => 1];
while (!empty($queue)) {
$step++;
$size = count($queue);
for ($sz = 0; $sz < $size; $sz++) {
$current = array_shift($queue);
foreach ($graph[$current] as $v) {
if (!isset($nodeToStep[$v])) {
$queue[] = $v;
$nodeToStep[$v] = $step + 1;
} elseif ($nodeToStep[$v] == $step) {
// There is an odd number of edges in the cycle.
return -1;
}
}
}
}
return $step;
}
class UnionFind {
/**
* @var array
*/
private $id;
/**
* @var array
*/
private $rank;
/**
* @param $n
*/
public function __construct($n) {
$this->id = range(0, $n - 1);
$this->rank = array_fill(0, $n, 0);
}
/**
* @param $u
* @param $v
* @return void
*/
public function unionByRank($u, $v) {
$i = $this->find($u);
$j = $this->find($v);
if ($i == $j) {
return;
}
if ($this->rank[$i] < $this->rank[$j]) {
$this->id[$i] = $j;
} elseif ($this->rank[$i] > $this->rank[$j]) {
$this->id[$j] = $i;
} else {
$this->id[$i] = $j;
$this->rank[$j]++;
}
}
/**
* @param $u
* @return mixed
*/
public function find($u) {
if ($this->id[$u] == $u) {
return $u;
}
return $this->id[$u] = $this->find($this->id[$u]);
}
}
// Example usage:
$n = 6;
$edges = [[1,2], [1,4], [1,5], [2,6], [2,3], [4,6]];
echo maxGroups($n, $edges); // Output: 4
$n = 3;
$edges = [[1,2], [2,3], [3,1]];
echo maxGroups($n, $edges); // Output: -1
?> Explanation:1. Union-Find ClassThe Union-Find (Disjoint Set Union) structure groups nodes into connected components and performs two main tasks:
2. BFS for Bipartite Check and Depth Calculation
3. Combine Results
Example WalkthroughExample 1Input: $n = 6;
$edges = [[1,2], [1,4], [1,5], [2,6], [2,3], [4,6]]; Steps:
Output: Example 2Input: $n = 3;
$edges = [[1,2], [2,3], [3,1]]; Steps:
Output: Time Complexity
Output for Examples$n = 6;
$edges = [[1,2], [1,4], [1,5], [2,6], [2,3], [4,6]];
echo magnificentSets($n, $edges); // Output: 4
$n = 3;
$edges = [[1,2], [2,3], [3,1]];
echo magnificentSets($n, $edges); // Output: -1 This approach efficiently handles the grouping problem by leveraging BFS for bipartiteness checks and depth calculations while utilizing Union-Find to simplify component management. The solution handles both connected and disconnected graphs. |
Beta Was this translation helpful? Give feedback.
The problem, "Divide Nodes Into the Maximum Number of Groups", involves determining the maximum number of groups into which the nodes of an undirected graph can be divided, such that:
If the graph is not bipartite, grouping is impossible, and the function must return
-1
.Key Points
-1
.Approach
Preprocessing: