leetcode2959
2959. 关闭分部的可行集合数目 - 力扣(LeetCode)
不会做,照着灵神把代码敲了一遍+ai理解
g = [[inf] * n for _ in range(n)]
初始化一个 `n` x `n` 的图的邻接矩阵 `g`,所有元素设为无穷大(`inf`),表示在没有道路连接的情况下,节点间的距离是无穷的。
for x, y, wt in roads:
遍历输入的 `roads` 列表,每次迭代得到一条道路的起点 `x`、终点 `y` 和权重 `wt`。
g[x][y] = min(g[x][y], wt)
g[y][x] = min(g[y][x], wt)
更新邻接矩阵 `g`,将起点到终点的权重设置为当前值和新权重 `wt` 中的较小者,同时因为是无向图,也要更新终点到起点的权重。
ans = 1 # s=0 一定满足要求
初始化答案变量 `ans` 为 1,因为状态 `s=0`(没有选择任何节点)总是满足要求。
f = [[[inf] * n for _ in range(n)] for _ in range(1 << n)]
初始化一个三维数组 `f`,用于存储从状态 `s` 到任意两个节点 `i` 和 `j` 的最小距离。`1 << n` 表示所有可能的状态数(2的n次方)。
f[0] = g
将 `f` 数组的第 0 个状态初始化为图的邻接矩阵 `g`。
遍历从 1 到 `2^n - 1` 的所有状态,每个状态 `s` 用二进制表示,每一位表示一个节点是否被选中。
k = s.bit_length() - 1
计算状态 `s` 的二进制表示中最高位的索引 `k`。
t = s ^ (1 << k)
计算状态 `s` 中除去最高位后的状态 `t`。
ok = 1
初始化一个标志变量 `ok`,用于检查当前状态 `s` 是否满足所有节点对的最大距离限制。
for i in range(n):
for j in range(n):
嵌套循环遍历所有节点对 `(i, j)`。
f[s][i][j] = min(f[t][i][j], f[t][i][k] + f[t][k][j])
对于当前状态 `s`,更新节点 `i` 到 `j` 的最小距离,取状态 `t` 下的直接距离或通过节点 `k` 的间接距离的较小者。
if ok and j < i and s >> i & 1 and s >> j & 1 and f[s][i][j] > maxDistance:
ok = 0
如果当前状态 `s` 仍然有效(`ok` 为 1),并且节点对 `(i, j)` 满足以下条件:
- `j < i`:确保不会重复计算同一对节点。
- `s >> i & 1` 和 `s >> j & 1`:检查节点 `i` 和 `j` 在状态 `s` 中是否都被选中。
- `f[s][i][j] > maxDistance`:节点对 `(i, j)` 的距离是否超过了最大距离限制。
如果这些条件都满足,且节点对的距离超过了限制,则将 `ok` 设置为 0,表示当前状态不满足要求。
ans += ok
如果当前状态 `s` 满足所有要求(`ok` 为 1),则将答案 `ans` 加一。
return ans
返回满足条件的集合数量。
class Solution:
def numberOfSets(self, n: int, maxDistance: int, roads: List[List[int]]) -> int:
g = [[inf] * n for _ in range(n)]
for x, y, wt in roads:
g[x][y] = min(g[x][y], wt)
g[y][x] = min(g[y][x], wt)
ans = 1 # s=0 一定满足要求
f = [[[inf] * n for _ in range(n)] for _ in range(1 << n)]
f[0] = g
for s in range(1, 1 << n):
k = s.bit_length() - 1
t = s ^ (1 << k)
ok = 1
for i in range(n):
for j in range(n):
f[s][i][j] = min(f[t][i][j], f[t][i][k] + f[t][k][j])
if ok and j < i and s >> i & 1 and s >> j & 1 and f[s][i][j] > maxDistance:
ok = 0
ans += ok
return ans
leetcode1334
1334. 阈值距离内邻居最少的城市 - 力扣(LeetCode)
floyd算法
class Solution:
def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
ans = (inf,-1)
grid = [[inf for _ in range(n)] for _ in range(n)]
for u,v,w in edges:
grid[u][v] = w
grid[v][u] = w
for start in range(n):
grid[start][start] = 0
for i in range(n):
for j in range(n):
grid[i][j] = min(grid[i][j],grid[i][start] + grid[start][j])
for i in range(n):
cnt = sum(grid[i][j] <= distanceThreshold for j in range(n))
if cnt <= ans[0]:
ans = (cnt,i)
return ans[1]