javascript bfs + dfs + topogical sort
bfs: 588ms (recommend)\n\nconst initializeGraph = (n) => { let g = []; for (let i = 0; i < n; i++) { g.push([]); } return g; };\nconst packDG = (g, edges) => { 
bfs: 588ms (recommend)\n```\nconst initializeGraph = (n) => { let g = []; for (let i = 0; i < n; i++) { g.push([]); } return g; };\nconst packDG = (g, edges) => { for (const [u, v] of edges) { g[u].push(v); } };\n\nconst getAncestors = (n, edges) => {\n    let g = initializeGraph(n), res = initializeGraph(n);\n    packDG(g, edges);\n    for (let i = 0; i < n; i++) { // start from i parent\n        let q = [i], visit = new Set([i]);\n        while (q.length) {\n            let cur = q.shift();\n            if (cur != i) res[cur].push(i); // each time set ancestor for current node, ignore parent itself\n            for (const child of g[cur]) {\n                if (visit.has(child)) continue;\n                visit.add(child);\n                q.push(child);\n            }\n        }\n    }\n    return res;\n};\n```\ntopogical sort 706ms  (recommend)\n```\nconst initializeGraph = (n) => { let g = []; for (let i = 0; i < n; i++) { g.push([]); } return g; };\nconst packDGInDegree = (g, edges, indegree) => { for (const [u, v] of edges) { g[u].push(v); indegree[v]++; } };\nconst initializeGraphSet = (n) => { let g = []; for (let i = 0; i < n; i++) { g.push(new Set()); } return g; };\n\nlet res;\nconst getAncestors = (n, edges) => {\n    let g = initializeGraph(n), indegree = Array(n).fill(0); // record depth of nodes\n    res = initializeGraphSet(n);\n    packDGInDegree(g, edges, indegree);\n    topologicalSort(g, indegree);\n    return res.map(se => [...se].sort((x, y) => x - y)); // convert inside set to sorted array\n};\n\nconst topologicalSort = (g, indegree) => {\n    let q = [], n = g.length;\n    for (let i = 0; i < n; i++) {\n        if (indegree[i] == 0) q.push(i); // set starting node/top parent/root of depth 0\n    }\n    while (q.length) {\n        let cur = q.shift();\n        for (const child of g[cur]) { // cur -> child\n            if (--indegree[child] == 0) q.push(child);\n            res[child].add(cur); // cur is parent, set ancestor for each child\n            for (const ancestor of res[cur]) res[child].add(ancestor); // remember to add parent\'s parents to child\n        }\n    }\n};\n```\ndfs: 468ms\n```\nconst initializeGraph = (n) => { let g = []; for (let i = 0; i < n; i++) { g.push([]); } return g; };\nconst packDGParent = (g, edges) => { for (const [u, v] of edges) { g[v].push(u); } };\nconst initializeGraphSet = (n) => { let g = []; for (let i = 0; i < n; i++) { g.push(new Set()); } return g; };\n\nlet g;\nconst getAncestors = (n, edges) => {\n    g = initializeGraph(n);\n    packDGParent(g, edges);\n    let res = initializeGraphSet(n), visit = Array(n).fill(false);\n    for (let i = 0; i < n; i++) {\n        if (!visit[i]) dfs(i, visit, res);\n    }\n    return res.map(se => [...se].sort((x, y) => x - y));\n};\n\nconst dfs = (cur, visit, res) => {\n    visit[cur] = true;\n    for (const child of g[cur]) {\n        if (!visit[child]) dfs(child, visit, res);\n        res[cur].add(child);\n        for (const ancestor of res[child]) res[cur].add(ancestor);\n    }\n};\n```
['Depth-First Search', 'Breadth-First Search', 'Topological Sort', 'JavaScript']