// hint based solution
func getAncestors(n int, edges [][]int) [][]int {
g := make([][]int, n) // reversed adj list
parents := make([]bool, n)
for _, v := range edges {
g[v[1]] = append(g[v[1]], v[0])
parents[v[0]] = true
}
ancestors := make([][]bool, n)
for i := range n {
ancestors[i] = make([]bool, n)
}
visited := make([]bool, n)
var dfs func(i int, descendants []int) // i is node
dfs = func(i int, descendants []int) {
if visited[i] {
for _, des := range descendants {
ancestors[des][i] = true
for anc, ok := range ancestors[i] {
if ok {
ancestors[des][anc] = true
}
}
}
// fmt.Printf("already visited node %v\n", i)
return
}
// fmt.Printf("visiting node %v \n", i)
visited[i] = true
for _, v := range descendants {
ancestors[v][i] = true
}
for _, next := range g[i] {
dfs(next, append(descendants , i))
}
}
for i, ok := range parents {
if !ok { // nonParents
// fmt.Printf("visiting nonParent %v\n", i)
dfs(i, []int{})
}
}
res := make([][]int, n)
for i, v := range ancestors {
for j := range v {
if ancestors[i][j] {
res[i] = append(res[i], j)
}
}
}
return res
}