Welcome to Subscribe On Youtube
3910. Count Connected Subgraphs with Even Node Sum
Description
You are given an undirected graph with n nodes labeled from 0 to n - 1. Node i has a value of nums[i], which is either 0 or 1. The edges of the graph are given by a 2D array edges where edges[i] = [ui, vi] represents an edge between node ui and node vi.
For a non-empty subset s of nodes in the graph, we consider the induced subgraph of s generated as follows:
- We keep only the nodes in
s. - We keep only the edges whose two endpoints are both in
s.
Return an integer representing the number of non-empty subsets s of nodes in the graph such that:
- The induced subgraph of
sis connected. - The sum of node values in
sis even.
Example 1:
Input: nums = [1,0,1], edges = [[0,1],[1,2]]
Output: 2
Explanation:
s |
connected? | sum of node values | counted? |
|---|---|---|---|
[0] |
Yes | 1 | No |
[1] |
Yes | 0 | Yes |
[2] |
Yes | 1 | No |
[0,1] |
Yes | 1 | No |
[0,2] |
No, node 0 and node 2 are disconnected. | 2 | No |
[1,2] |
Yes | 1 | No |
[0,1,2] |
Yes | 2 | Yes |
Example 2:
Input: nums = [1], edges = []
Output: 0
Explanation:
s |
connected? | sum of node values | counted? |
|---|---|---|---|
[0] |
Yes | 1 | No |
Constraints:
1 <= n == nums.length <= 13nums[i]is 0 or 1.0 <= edges.length <= n * (n - 1) / 2edges[i] = [ui, vi]0 <= ui < vi < n- All edges are distinct.
Solutions
Solution 1: Bitmask Enumeration + DFS
Notice that the number of nodes in the problem does not exceed $13$, so we can enumerate all non-empty subsets $s$ of nodes. For each subset, we calculate the total sum of node values and check whether its induced subgraph is connected.
Specifically, we can use an integer $sub$ to represent the subset $s$, where the $i$-th bit of $sub$ is $1$ if node $i$ is in the subset, and $0$ otherwise. For each subset, we first compute the sum of its node values. If the sum is odd, we skip this subset; otherwise, we use DFS to check whether the induced subgraph is connected. We can use an integer $vis$ to represent the visited nodes: initially, the $i$-th bit of $vis$ is $1$ if node $i$ is not in the subset, and $0$ if node $i$ is in the subset. We start DFS from any node in subset $s$, visit all its adjacent nodes, and mark visited nodes in $vis$ as $1$. Finally, if all bits in $vis$ are $1$, it means the induced subgraph of subset $s$ is connected, so we increment the answer by $1$.
The time complexity is $O(2^n \times (n + m))$ and the space complexity is $O(n + m)$, where $n$ and $m$ are the number of nodes and edges, respectively.
-
class Solution { private int vis; private int m; private List<Integer>[] g; public int evenSumSubgraphs(int[] nums, int[][] edges) { int n = nums.length; g = new List[n]; Arrays.setAll(g, k -> new ArrayList<>()); for (int[] e : edges) { g[e[0]].add(e[1]); g[e[1]].add(e[0]); } m = (1 << n) - 1; int ans = 0; for (int sub = 1; sub <= m; sub++) { int s = 0; for (int i = 0; i < n; i++) { if (((sub >> i) & 1) == 1) { s += nums[i]; } } if (s % 2 != 0) { continue; } vis = m ^ sub; dfs(Integer.numberOfTrailingZeros(sub)); if (vis == m) { ans++; } } return ans; } private void dfs(int u) { vis |= 1 << u; for (int v : g[u]) { if (((vis >> v) & 1) == 0) { dfs(v); } } } } -
class Solution { public: int evenSumSubgraphs(vector<int>& nums, vector<vector<int>>& edges) { int n = nums.size(); vector<vector<int>> g(n); for (auto& e : edges) { g[e[0]].push_back(e[1]); g[e[1]].push_back(e[0]); } int m = (1 << n) - 1; int ans = 0; int vis; auto dfs = [&](this auto dfs, int u) -> void { vis |= 1 << u; for (int v : g[u]) { if (((vis >> v) & 1) == 0) { dfs(v); } } }; for (int sub = 1; sub <= m; sub++) { int s = 0; for (int i = 0; i < n; i++) { if ((sub >> i) & 1) { s += nums[i]; } } if (s % 2 != 0) { continue; } vis = m ^ sub; dfs(31 - __builtin_clz(sub)); if (vis == m) { ans++; } } return ans; } }; -
class Solution: def evenSumSubgraphs(self, nums: list[int], edges: list[list[int]]) -> int: n = len(nums) g = [[] for _ in range(n)] for u, v in edges: g[u].append(v) g[v].append(u) m = (1 << n) - 1 ans = 0 for sub in range(1, m + 1): s = sum(x for i, x in enumerate(nums) if sub >> i & 1) if s % 2: continue vis = m ^ sub def dfs(u: int) -> None: nonlocal vis vis |= 1 << u for v in g[u]: if (vis >> v & 1) == 0: dfs(v) dfs(sub.bit_length() - 1) if vis == m: ans += 1 return ans -
func evenSumSubgraphs(nums []int, edges [][]int) int { n := len(nums) g := make([][]int, n) for _, e := range edges { g[e[0]] = append(g[e[0]], e[1]) g[e[1]] = append(g[e[1]], e[0]) } m := (1 << n) - 1 ans := 0 var vis int var dfs func(int) dfs = func(u int) { vis |= 1 << u for _, v := range g[u] { if (vis >> v & 1) == 0 { dfs(v) } } } for sub := 1; sub <= m; sub++ { s := 0 for i := 0; i < n; i++ { if sub>>i&1 == 1 { s += nums[i] } } if s%2 != 0 { continue } vis = m ^ sub dfs(bits.Len(uint(sub)) - 1) if vis == m { ans++ } } return ans } -
function evenSumSubgraphs(nums: number[], edges: number[][]): number { const n = nums.length; const g: number[][] = Array.from({ length: n }, () => []); for (const [u, v] of edges) { g[u].push(v); g[v].push(u); } const m = (1 << n) - 1; let ans = 0; let vis = 0; const dfs = (u: number): void => { vis |= 1 << u; for (const v of g[u]) { if (((vis >> v) & 1) === 0) { dfs(v); } } }; for (let sub = 1; sub <= m; sub++) { let s = 0; for (let i = 0; i < n; i++) { if ((sub >> i) & 1) { s += nums[i]; } } if (s % 2 !== 0) { continue; } vis = m ^ sub; dfs(sub.toString(2).length - 1); if (vis === m) { ans++; } } return ans; }