首页 > 其他分享 >leetcode 6256. 将节点分成尽可能多的组 二分图判定+bfs+并查集

leetcode 6256. 将节点分成尽可能多的组 二分图判定+bfs+并查集

时间:2022-12-04 23:22:39浏览次数:68  
标签:return int self 查集 leetcode color 节点 6256 def

6256. 将节点分成尽可能多的组

难度困难

给你一个正整数 n ,表示一个 无向 图中的节点数目,节点编号从 1 到 n 。

同时给你一个二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示节点 ai 和 bi 之间有一条 双向 边。注意给定的图可能是不连通的。

请你将图划分为 m 个组(编号从 1 开始),满足以下要求:

  • 图中每个节点都只属于一个组。
  • 图中每条边连接的两个点 [ai, bi] ,如果 ai 属于编号为 x 的组,bi 属于编号为 y 的组,那么 |y - x| = 1 。

请你返回最多可以将节点分为多少个组(也就是最大的 m )。如果没办法在给定条件下分组,请你返回 -1 。

 

示例 1:

输入:n = 6, edges = [[1,2],[1,4],[1,5],[2,6],[2,3],[4,6]]
输出:4
解释:如上图所示,
- 节点 5 在第一个组。
- 节点 1 在第二个组。
- 节点 2 和节点 4 在第三个组。
- 节点 3 和节点 6 在第四个组。
所有边都满足题目要求。
如果我们创建第五个组,将第三个组或者第四个组中任何一个节点放到第五个组,至少有一条边连接的两个节点所属的组编号不符合题目要求。

示例 2:

输入:n = 3, edges = [[1,2],[2,3],[3,1]]
输出:-1
解释:如果我们将节点 1 放入第一个组,节点 2 放入第二个组,节点 3 放入第三个组,前两条边满足题目要求,但第三条边不满足题目要求。
没有任何符合题目要求的分组方式。

 

提示:

  • 1 <= n <= 500
  • 1 <= edges.length <= 104
  • edges[i].length == 2
  • 1 <= ai, bi <= n
  • ai != bi
  • 两个点之间至多只有一条边

 

解法一
class Solution: def magnificentSets(self, n: int, edges: List[List[int]]) -> int: adjList = [[] for _ in range(n)] uf = UnionFind(n) for u, v in edges: u, v = u - 1, v - 1 adjList[u].append(v) adjList[v].append(u) uf.union(u, v) if not isBipartite(n, adjList): return -1 return sum(calDiameter(n, adjList, group) + 1 for group in uf.getGroups().values()) def calDiameter(n: int, adjList: List[List[int]], group: List[int]) -> int: """bfs求连通分量 `group` 的直径长度""" res = 0 for start in group: visited, queue = set([start]), deque([start]) diameter = -1 while queue: len_ = len(queue) for _ in range(len_): cur = queue.popleft() for next in adjList[cur]: if next in visited: continue visited.add(next) queue.append(next) diameter += 1 res = max(res, diameter) return res def isBipartite(n: int, adjList: List[List[int]]) -> bool: """二分图检测 dfs染色""" def dfs(cur: int, color: int) -> bool: colors[cur] = color for next in adjList[cur]: if colors[next] == -1: if not dfs(next, color ^ 1): return False elif colors[next] == color: return False return True colors = [-1] * n for i in range(n): if colors[i] == -1 and not dfs(i, 0): return False return True class UnionFind: def __init__(self, n: int): self.n = n self.part = n self.parent = list(range(n)) self.rank = [1] * n def find(self, x: int) -> int: while x != self.parent[x]: self.parent[x] = self.parent[self.parent[x]] x = self.parent[x] return x def union(self, x: int, y: int) -> bool: rootX = self.find(x) rootY = self.find(y) if rootX == rootY: return False if self.rank[rootX] > self.rank[rootY]: rootX, rootY = rootY, rootX self.parent[rootX] = rootY self.rank[rootY] += self.rank[rootX] self.part -= 1 return True def getGroups(self) -> DefaultDict[int, List[int]]: groups = defaultdict(list) for key in range(self.n): root = self.find(key) groups[root].append(key) return groups

  

解法二
# class Solution:
#     def magnificentSets(self, n: int, edges: List[List[int]]) -> int:        
#         g = [[] for _ in range(n)]
#         for x, y in edges:
#             g[x - 1].append(y -1)
#             g[y - 1].append(x - 1)

#         time = [0] * n 
#         clock = 0 
#         def bfs(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:
#                             time[y] = clock
#                             q.append(y)
#                 depth += 1 
#             return depth

#         color = [0] * n 
#         def is_bipartite(x, c):
#             nodes.append(x)
#             color[x] = c 
#             for y in g[x]:
#                 if color[y] == c or color[y] == 0 and not is_bipartite(y, -c):
#                     return False
#             return True 

#         ans = 0 
#         for i, c in enumerate(color):
#             if c: continue 
#             nodes = [] 
#             print (color)
#             t = is_bipartite(i, 1)
#             print (color)
#             if not t: return -1 
#             ans += max(bfs(x) for x in nodes)
#             print (ans)
        
#         return ans

 

标签:return,int,self,查集,leetcode,color,节点,6256,def
From: https://www.cnblogs.com/xianbin7/p/16951173.html

相关文章

  • #yyds干货盘点# LeetCode程序员面试金典:零矩阵
    题目:编写一种算法,若M×N矩阵中某个元素为0,则将其所在的行与列清零。 示例1:输入:[ [1,1,1], [1,0,1], [1,1,1]]输出:[ [1,0,1], [0,0,0], [1,0,1]]示例2:输入:[......
  • 力扣 leetcode 209. 长度最小的子数组
    问题描述给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其和≥target的长度最小的连续子数组[numsl,numsl+1,...,numsr-1,numsr],并返......
  • LeetCode刷题记录.Day31
    二叉树的层序遍历递归法classSolution{public:voidorder(TreeNode*cur,vector<vector<int>>&result,intdepth){if(cur==nullptr)retur......
  • Leetcode刷题第五周
    二叉树:种类:满二叉树、完全二叉树、二叉搜索树、平衡二叉搜索树存储方式:链式存储、线式存储(顺序存储)二叉数遍历:深度优先搜索(前序、中序、后序):使用递归实现(实际用栈来实现......
  • LeetCode:NO.142环形链表Ⅱ
    题目描述给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表......
  • 力扣 leetcode 547. 省份数量
    问题描述有n个城市,其中一些彼此相连,另一些没有相连。如果城市a与城市b直接相连,且城市b与城市c直接相连,那么城市a与城市c间接相连。省份是一组直接或间接......
  • 力扣 leetcode 200. 岛屿数量
    问题描述给你一个由'1'(陆地)和'0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此......
  • 两两交换链表中的节点-LeetCode24模拟节点
    力扣链接:https://leetcode.cn/problems/swap-nodes-in-pairs/题目给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完......
  • [LeetCode] 1323. Maximum 69 Number 6和9组成的最大数字
    Youaregivenapositiveinteger num consistingonlyofdigits 6 and 9.Return themaximumnumberyoucangetbychanging atmost onedigit(6* becom......
  • leetcode.cn 17.电话号码的字母组合 - 生成组合数
    这题难度标为“中等”,那肯定不难。看完题,知道就是生成组合数。想起当年上学的时候我还做过一个组合工具类。于是在磁盘上搜索,找到一看,原来当年是Java写的一个类,代码也很简......