# 2192. All Ancestors of a Node in a Directed Acyclic Graph
###### tags: `Leetcode` `Medium` `Topological Sort` `BFS`
Link: https://leetcode.com/problems/all-ancestors-of-a-node-in-a-directed-acyclic-graph/
## 思路
### 思路一 Topological Sort $O(N^2logN)$ $O(N^2)$
和[1462. Course Schedule IV](https://hackmd.io/QrubTV-KT9CEUdjsdvd7lw)的思路有点像
都是找到每个node的ancestor
做法是先建graph 然后在bfs的同时存ancestor
由于输出的ancestor要按顺序 所以先用了treeset 之后再output到list里面
### 思路二 DFS $O(N^2)$ $O(N^2)$ (more efficient)
先建图 记录每个node的child
然后对于每一个node做dfs 找到它所有的child 并且在它的child的ancestor list上加上他自己
这样不用排序 就可以得到答案
但问题在于如果A->B B->C A->C的话那么A就会被加进C的ancestor list两次 所以需要加之前需要检验一下是不是已经访问过了
## Code
### 思路一 Topological Sort $O(N^2)$ $O(N^2)$
```java=
class Solution {
public List<List<Integer>> getAncestors(int n, int[][] edges) {
List<List<Integer>> graph = new ArrayList<>();
List<Set<Integer>> ancestor = new ArrayList<>();
int[] ancestorNum = new int[n];
for(int i=0; i<n; i++){
graph.add(new ArrayList<>());
ancestor.add(new TreeSet<>());
}
for(int[] edge:edges){
int a = edge[0], b = edge[1];
graph.get(a).add(b);
ancestorNum[b]++;
}
Queue<Integer> q = new LinkedList<>();
for(int i=0; i<n; i++){
if(ancestorNum[i]==0) q.add(i);
}
while(!q.isEmpty()){
int curr = q.poll();
for(int next:graph.get(curr)){
ancestor.get(next).add(curr);
ancestor.get(next).addAll(ancestor.get(curr));
ancestorNum[next]--;
if(ancestorNum[next]==0) q.add(next);
}
}
List<List<Integer>> ans = new ArrayList<>();
for(int i=0; i<n; i++){
ans.add(new ArrayList<>(ancestor.get(i)));
}
return ans;
}
}
```
### 思路二 DFS $O(N^2)$ $O(N^2)$ (more efficient)
```python=
class Solution:
def getAncestors(self, n: int, edges: List[List[int]]) -> List[List[int]]:
ans = [[] for _ in range(n)]
graph = [[] for _ in range(n)]
visited = [False]*n
for a, b in edges:
graph[a].append(b)
def dfs(start, curr):
for nextNode in graph[curr]:
if len(ans[nextNode])==0 or ans[nextNode][-1]!=start:
ans[nextNode].append(start)
dfs(start, nextNode)
for i in range(n):
dfs(i, i)
return ans
```
```java=
class Solution {
public List<List<Integer>> getAncestors(int n, int[][] edges) {
List<List<Integer>> graph = new ArrayList<>();
List<List<Integer>> ans = new ArrayList<>();
for(int i=0; i<n; i++){
graph.add(new ArrayList<>());
ans.add(new ArrayList<>());
}
for(int[] edge:edges){
graph.get(edge[0]).add(edge[1]);
}
for(int i=0; i<n; i++){
dfs(ans, graph, i, i);
}
return ans;
}
private void dfs(List<List<Integer>> ans, List<List<Integer>> graph, int curr, int anc){
for(int next:graph.get(curr)){
if(ans.get(next).size()==0 || ans.get(next).get(ans.get(next).size()-1)!=anc){
ans.get(next).add(anc);
dfs(ans, graph, next, anc);
}
}
}
}
```