classSolution: defmagnificentSets(self, n: int, edges: List[List[int]]) -> int: g = [[] for _ inrange(n)] for x, y in edges: g[x - 1].append(y - 1) g[y - 1].append(x - 1)
time = [0] * n # 充当 vis 数组的作用(避免在 BFS 内部重复创建 vis 数组) clock = 0 defbfs(start: int) -> int: # 返回从 start 出发的最大深度 depth = 0 nonlocal clock clock += 1 time[start] = clock q = [start] while q: tmp = q q = [] for x in tmp: for y in g[x]: if time[y] != clock: # 没有在同一次 BFS 中访问过 time[y] = clock q.append(y) depth += 1 return depth
color = [0] * n defis_bipartite(x: int, c: int) -> bool: # 二分图判定,原理见视频讲解 nodes.append(x) color[x] = c for y in g[x]: if color[y] == c or color[y] == 0andnot is_bipartite(y, -c): returnFalse returnTrue
ans = 0 for i, c inenumerate(color): if c: continue nodes = [] ifnot is_bipartite(i, 1): return -1# 如果不是二分图(有奇环),则无法分组 # 否则一定可以分组 ans += max(bfs(x) for x in nodes) # 枚举连通块的每个点,作为起点 BFS,求最大深度 return ans
classSolution { private List<Integer>[] g; privatefinal List<Integer> nodes = newArrayList<>(); privateint[] time, color; // time 充当 vis 数组的作用(避免在 BFS 内部重复创建 vis 数组) privateint clock;
publicintmagnificentSets(int n, int[][] edges) { g = newArrayList[n]; Arrays.setAll(g, e -> newArrayList<>()); for (var e : edges) { intx= e[0] - 1, y = e[1] - 1; g[x].add(y); g[y].add(x); }
time = newint[n]; color = newint[n]; varans=0; for (vari=0; i < n; i++) { if (color[i] != 0) continue; nodes.clear(); if (!isBipartite(i, 1)) return -1; // 如果不是二分图(有奇环),则无法分组 // 否则一定可以分组 varmaxDepth=0; for (var x : nodes) // 枚举连通块的每个点,作为起点 BFS,求最大深度 maxDepth = Math.max(maxDepth, bfs(x)); ans += maxDepth; } return ans; }
// 二分图判定,原理见视频讲解 privatebooleanisBipartite(int x, int c) { nodes.add(x); color[x] = c; for (var y : g[x]) if (color[y] == c || color[y] == 0 && !isBipartite(y, -c)) returnfalse; returntrue; }
// 返回从 start 出发的最大深度 privateintbfs(int start) { vardepth=0; time[start] = ++clock; varq=newArrayList<Integer>(); q.add(start); while (!q.isEmpty()) { vartmp= q; q = newArrayList<>(); for (var x : tmp) for (var y : g[x]) if (time[y] != clock) { // 没有在同一次 BFS 中访问过 time[y] = clock; q.add(y); } ++depth; } return depth; } }
classSolution { public: intmagnificentSets(int n, vector<vector<int>> &edges){ vector<vector<int>> g(n); for (auto &e : edges) { int x = e[0] - 1, y = e[1] - 1; g[x].push_back(y); g[y].push_back(x); }
int time[n], clock = 0; // time 充当 vis 数组的作用(避免在 BFS 内部重复创建 vis 数组) memset(time, 0, sizeof(time)); auto bfs = [&](int start) -> int { // 返回从 start 出发的最大深度 int depth = 0; time[start] = ++clock; vector<int> q = {start}; while (!q.empty()) { vector<int> nxt; for (int x : q) for (int y : g[x]) if (time[y] != clock) { // 没有在同一次 BFS 中访问过 time[y] = clock; nxt.push_back(y); } q = move(nxt); ++depth; } return depth; };
int8_t color[n]; memset(color, 0, sizeof(color)); vector<int> nodes; function<bool(int, int8_t)> is_bipartite = [&](int x, int8_t c) -> bool { // 二分图判定,原理见视频讲解 nodes.push_back(x); color[x] = c; for (int y : g[x]) if (color[y] == c || color[y] == 0 && !is_bipartite(y, -c)) returnfalse; returntrue; };
int ans = 0; for (int i = 0; i < n; ++i) { if (color[i]) continue; nodes.clear(); if (!is_bipartite(i, 1)) return-1; // 如果不是二分图(有奇环),则无法分组 // 否则一定可以分组 int max_depth = 0; for (int x : nodes) // 枚举连通块的每个点,作为起点 BFS,求最大深度 max_depth = max(max_depth, bfs(x)); ans += max_depth; } return ans; } };