Graph Valid Tree
Description
null
Solution(javascript)
// 1. 什么样的图是树?没有环而且不是森林
// 2. 无向图检测是否有环?DFS/Union Find
// /** 1: DFS
// * @param {number} n
// * @param {number[][]} edges
// * @return {boolean}
// */
// const validTree = function (n, edges) {
// const adj = edges.reduce((acc, [a, b]) => {
// acc[a] = acc[a] || []
// acc[a].push(b)
// acc[b] = acc[b] || []
// acc[b].push(a)
// return acc
// }, {})
// const root = 0
// const parent = {
// [root]: -1,
// }
// let size = 1
// let hasCycle = false
// const dfs = (node) => {
// (adj[node] || []).forEach((next) => {
// if (parent[next] === undefined) {
// size += 1
// parent[next] = node
// dfs(next)
// } else { // visited
// if (next !== parent[node]) {
// hasCycle = true
// }
// }
// })
// }
// dfs(root)
// return !hasCycle && size === n
// }
/** 1: Union Find
* @param {number} n
* @param {number[][]} edges
* @return {boolean}
*/
const validTree = function (n, edges) {
const parent = new Array(n).fill(0).map((x, index) => index)
const size = new Array(n).fill(0).map(() => 1)
let count = n
const root = (a) => {
while (a !== parent[a]) {
parent[a] = parent[parent[a]]
a = parent[a]
}
return a
}
const union = (a, b) => {
const rootA = root(a)
const rootB = root(b)
if (rootA === rootB) {
return
}
count -= 1
if (size[rootA] < size[rootB]) {
parent[rootA] = rootB
size[rootB] += size[rootA]
} else {
parent[rootB] = rootA
size[rootA] += size[rootB]
}
}
const connected = (a, b) => root(a) === root(b)
for (const [a, b] of edges) {
if (connected(a, b)) {
return false
}
union(a, b)
}
return count === 1
}