/* 问题描述: 有向无环图中一个节点的所有祖先。 给你一个正整数 n ,它表示一个 有向无环图 中节点的数目,节点编号为 0 到 n - 1 (包括两者)。 给你一个二维整数数组 edges ,其中 edges[i] = [fromi, toi] 表示图中一条从 fromi 到 toi 的单向边。 请你返回一个数组 answer,其中 answer[i]是第 i 个节点的所有 祖先 ,这些祖先节点 升序 排序。 如果 u 通过一系列边,能够到达 v ,那么我们称节点 u 是节点 v 的 祖先 节点。 输入:n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]] 输出:[[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]] 解释: 上图为输入所对应的图。 - 节点 0 ,1 和 2 没有任何祖先。 - 节点 3 有 2 个祖先 0 和 1 。 - 节点 4 有 2 个祖先 0 和 2 。 - 节点 5 有 3 个祖先 0 ,1 和 3 。 - 节点 6 有 5 个祖先 0 ,1 ,2 ,3 和 4 。 - 节点 7 有 4 个祖先 0 ,1 ,2 和 3 。 */ #include using namespace std; class Solution { public: vector> getAncestors(int n, vector>& edges) { vector> anc(n); // 存储每个节点祖先的辅助数组 vector> e(n); // 邻接表 vector indeg(n); // 入度表 // 预处理 for (const auto& edge: edges) { e[edge[0]].push_back(edge[1]); ++indeg[edge[1]]; } // 广度优先搜索求解拓扑排序 queue q; for (int i = 0; i < n; ++i) { if (!indeg[i]) { q.push(i); } } while (!q.empty()) { int u = q.front(); q.pop(); for (int v: e[u]) { // 更新子节点的祖先哈希表 anc[v].insert(u); for (int i: anc[u]) { anc[v].insert(i); } --indeg[v]; if (!indeg[v]) { q.push(v); } } } // 转化为答案数组 vector> res(n); for (int i = 0; i < n; ++i) { for (int j: anc[i]) { res[i].push_back(j); } sort(res[i].begin(), res[i].end()); } return res; } }; int main(){ Solution test; int n = 8; //[[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]] vector> nums = {{0,3},{0,4},{1,3},{2,4},{2,7},{3,5},{3,6},{3,7},{4,6}}; vector> res = test.getAncestors(n, nums); for(int i = 0; i < res.size(); i++){ for(int j = 0; j < res[i].size(); j++){ cout << res[i][j]; } cout << endl; } return 0; }