拓扑排序
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> findOrder(int numCourses, vector<vector<int>> &prerequisites) { |
| vector<int> res; |
| |
| vector<int> in_degree(numCourses, 0); |
| |
| vector<vector<int>> graph(numCourses); |
| |
| for (const auto &item: prerequisites) { |
| graph[item[1]].emplace_back(item[0]); |
| in_degree[item[0]]++; |
| } |
| |
| |
| queue<int> q; |
| for (int i = 0; i < numCourses; ++i) |
| if (in_degree[i] == 0) q.emplace(i); |
| |
| |
| int count = 0; |
| while (!q.empty()) { |
| |
| int node = q.front(); |
| q.pop(); |
| |
| res.emplace_back(node); |
| count++; |
| |
| |
| for (const auto &next: graph[node]){ |
| |
| in_degree[next]--; |
| |
| if (in_degree[next] == 0) q.emplace(next); |
| } |
| } |
| |
| return count == numCourses ? res : vector<int>(); |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| |
| using namespace std; |
| |
| |
| int main() { |
| int n, m; |
| cin >> n >> m; |
| vector<pair<int, int>> edges(m); |
| for (int i = 0; i < m; ++i) |
| cin >> edges[i].first >> edges[i].second; |
| |
| |
| |
| vector<vector<int>> graph(n + 1); |
| |
| vector<int> in_degree(n + 1, 0); |
| for (const auto &edge: edges) { |
| graph[edge.first].emplace_back(edge.second); |
| in_degree[edge.second]++; |
| } |
| |
| |
| queue<int> q; |
| for (int i = 1; i <= n; ++i) |
| if (in_degree[i] == 0) |
| q.emplace(i); |
| |
| vector<int> res(n); |
| int count = 0; |
| |
| while (!q.empty()) { |
| int node = q.front(); |
| q.pop(); |
| res[count++] = node; |
| |
| for (int i = 0; i < graph[node].size(); ++i) { |
| |
| int next = graph[node][i]; |
| in_degree[next]--; |
| if (in_degree[next] == 0) q.emplace(next); |
| } |
| } |
| |
| if (count == n) { |
| for (int i = 0; i < n - 1; ++i) |
| cout << res[i] << " "; |
| cout << res[n - 1]; |
| } else { |
| cout << -1; |
| } |
| } |
- 有向无环图上有n个点,m条边。求这张图字典序最小的拓扑排序的结果。字典序最小指希望排好序的结果中,比较靠前的数字尽可能小。
- 把存放入度为 0 的队列换成小顶堆即可按字典序输出
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| |
| using namespace std; |
| |
| int main() { |
| int n, m; |
| cin >> n >> m; |
| vector<pair<int, int>> edges(m); |
| for (int i = 0; i < m; ++i) |
| cin >> edges[i].first >> edges[i].second; |
| |
| |
| |
| vector<vector<int>> graph(n + 1); |
| |
| vector<int> in_degree(n + 1, 0); |
| for (const auto &edge: edges) { |
| graph[edge.first].emplace_back(edge.second); |
| in_degree[edge.second]++; |
| } |
| |
| |
| priority_queue<int, vector<int>, greater<>> q; |
| for (int i = 1; i <= n; ++i) |
| if (in_degree[i] == 0) |
| q.push(i); |
| |
| vector<int> res(n); |
| int count = 0; |
| |
| while (!q.empty()) { |
| int node = q.top(); |
| q.pop(); |
| res[count++] = node; |
| |
| for (int i = 0; i < graph[node].size(); ++i) { |
| |
| int next = graph[node][i]; |
| in_degree[next]--; |
| if (in_degree[next] == 0) q.push(next); |
| } |
| } |
| |
| if (count == n) { |
| for (int i = 0; i < n - 1; ++i) |
| cout << res[i] << " "; |
| cout << res[n - 1]; |
| } else { |
| cout << -1; |
| } |
| } |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| |
| vector<int> head; |
| vector<int> nxt; |
| vector<int> to; |
| int edgeIndex = 0; |
| vector<int> in_degree; |
| |
| void addEdge(int u, int v) { |
| edgeIndex++; |
| nxt[edgeIndex] = head[u]; |
| to[edgeIndex] = v; |
| head[u] = edgeIndex; |
| } |
| |
| |
| void buildGraph(int vertexNum, int edgeNum, vector<pair<int, int>> &edges) { |
| head.resize(vertexNum, 0); |
| nxt.resize(edgeNum); |
| to.resize(edgeNum); |
| for (const auto &item: edges) |
| addEdge(item.first, item.second); |
| } |
| |
| |
| vector<int> heap; |
| int lenOfHeap; |
| |
| void buildHeap(int max) { |
| heap.resize(max); |
| lenOfHeap = 0; |
| } |
| |
| |
| void adjustHeap(int curIndex) { |
| int val = heap[curIndex]; |
| int leftChild = 2 * curIndex + 1; |
| while (leftChild <= (lenOfHeap - 1)) { |
| |
| if ((leftChild < (lenOfHeap - 1)) |
| && heap[leftChild] > heap[leftChild + 1]) |
| leftChild++; |
| |
| if (heap[leftChild] >= val) break; |
| |
| heap[curIndex] = heap[leftChild]; |
| curIndex = leftChild; |
| leftChild = 2 * curIndex + 1; |
| } |
| heap[curIndex] = val; |
| } |
| |
| void push(int val) { |
| int curIndex = lenOfHeap; |
| |
| lenOfHeap++; |
| |
| int parentIndex = (curIndex - 1) >> 1; |
| |
| while (parentIndex >= 0 && heap[parentIndex] > val) { |
| |
| heap[curIndex] = heap[parentIndex]; |
| curIndex = parentIndex; |
| parentIndex = (curIndex - 1) >> 1; |
| } |
| |
| heap[curIndex] = val; |
| } |
| |
| int getTop() { |
| int res = heap[0]; |
| |
| heap[0] = heap[lenOfHeap - 1]; |
| lenOfHeap--; |
| |
| adjustHeap(0); |
| return res; |
| } |
| |
| |
| int main() { |
| int n, m; |
| cin >> n >> m; |
| vector<pair<int, int>> edges(m); |
| for (int i = 0; i < m; ++i) |
| cin >> edges[i].first >> edges[i].second; |
| |
| buildGraph(n + 1, m + 1, edges); |
| buildHeap(n + 1); |
| |
| |
| in_degree.resize(n + 1, 0); |
| for (const auto &item: edges) |
| in_degree[item.second]++; |
| |
| |
| for (int i = 1; i < in_degree.size(); ++i) |
| if (in_degree[i] == 0) push(i); |
| |
| vector<int> res(n); |
| int resIndex = 0; |
| |
| while (lenOfHeap != 0) { |
| int v = getTop(); |
| res[resIndex++] = v; |
| |
| int e = head[v]; |
| while (e > 0) { |
| in_degree[to[e]]--; |
| if (in_degree[to[e]] == 0) push(to[e]); |
| e = nxt[e]; |
| } |
| } |
| |
| if (resIndex == n) { |
| for (int i = 0; i < n - 1; ++i) |
| cout << res[i] << " "; |
| cout << res[n - 1]; |
| } else { |
| cout << -1; |
| } |
| } |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| string alienOrder(vector<string> &words) { |
| |
| vector<int> in_degree(26, -1); |
| |
| for (const auto &str: words) |
| for (int i = 0; i < str.length(); ++i) |
| in_degree[str[i] - 'a'] = 0; |
| |
| |
| vector<vector<int>> graph(26); |
| for (int i = 0; i < words.size() - 1; ++i) { |
| string cur = words[i]; |
| string nxt = words[i + 1]; |
| int j = 0; |
| int len = min(cur.length(), nxt.length()); |
| while (j < len) { |
| if (cur[j] != nxt[j]) { |
| |
| graph[cur[j] - 'a'].emplace_back(nxt[j] - 'a'); |
| in_degree[nxt[j] - 'a']++; |
| break; |
| } |
| j++; |
| } |
| |
| if (j < cur.length() && j == nxt.length()) return ""; |
| } |
| |
| queue<int> q; |
| |
| int kinds = 0; |
| for (int i = 0; i < 26; ++i) { |
| if (in_degree[i] != -1) kinds++; |
| if (in_degree[i] == 0) q.push(i); |
| } |
| |
| string res = ""; |
| while (!q.empty()) { |
| int cur = q.front(); |
| q.pop(); |
| |
| res.append(1, cur + 'a'); |
| for (const auto &item: graph[cur]) { |
| in_degree[item]--; |
| if (in_degree[item] == 0) q.push(item); |
| } |
| } |
| return res.length() == kinds ? res : ""; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> movesToStamp(string stamp, string target) { |
| int m = stamp.length(); |
| int n = target.length(); |
| |
| vector<int> in_degree(n - m + 1, m); |
| |
| vector<vector<int>> graph(n); |
| queue<int> q; |
| |
| for (int i = 0; i <= n - m; ++i) { |
| for (int j = 0; j < m; ++j) { |
| if (target[i + j] == stamp[j]) { |
| |
| in_degree[i]--; |
| |
| if (in_degree[i] == 0) q.push(i); |
| } else { |
| |
| graph[i + j].emplace_back(i); |
| } |
| } |
| } |
| |
| vector<bool> visited(n); |
| vector<int> res(n - m + 1); |
| int size = 0; |
| while (!q.empty()) { |
| int v = q.front(); |
| q.pop(); |
| |
| res[size++] = v; |
| |
| for (int i = 0; i < m; ++i) { |
| |
| if (visited[v + i] == true) continue; |
| |
| visited[v + i] = true; |
| |
| |
| for (const auto &item: graph[v + i]) { |
| in_degree[item]--; |
| |
| if (in_degree[item] == 0) q.push(item); |
| } |
| } |
| } |
| if (size != n - m + 1) return vector<int>(); |
| |
| reverse(begin(res), end(res)); |
| return res; |
| } |
| }; |
- 利用拓扑排序的过程,将上游节点的信息逐渐传递到下游节点
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| int main() { |
| int MOD = 80112002; |
| int n, m; |
| cin >> n >> m; |
| vector<pair<int, int>> edges(m); |
| for (int i = 0; i < m; ++i) |
| cin >> edges[i].first >> edges[i].second; |
| |
| |
| vector<vector<int>> graph(n + 1); |
| vector<int> in_degree(n + 1, 0); |
| for (const auto &item: edges) { |
| graph[item.first].emplace_back(item.second); |
| in_degree[item.second]++; |
| } |
| |
| queue<int> q; |
| |
| vector<int> path(n + 1, 0); |
| for (int i = 1; i <= n; ++i) { |
| if (in_degree[i] == 0) { |
| q.push(i); |
| path[i] = 1; |
| } |
| } |
| |
| int res = 0; |
| while (!q.empty()) { |
| int v = q.front(); |
| q.pop(); |
| if (graph[v].size() == 0) { |
| |
| res = (res + path[v]) % MOD; |
| } else { |
| for (const auto &item: graph[v]) { |
| in_degree[item]--; |
| if (in_degree[item] == 0) q.push(item); |
| |
| path[item] = (path[item] + path[v]) % MOD; |
| } |
| } |
| } |
| |
| cout << res; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> loudAndRich(vector<vector<int>> &richer, vector<int> &quiet) { |
| int n = quiet.size(); |
| |
| vector<int> in_degree(n, 0); |
| |
| vector<vector<int>> graph(n); |
| |
| for (const auto &item: richer) { |
| graph[item[0]].emplace_back(item[1]); |
| in_degree[item[1]]++; |
| } |
| |
| queue<int> q; |
| for (int i = 0; i < n; ++i) |
| if (in_degree[i] == 0) |
| q.push(i); |
| |
| |
| vector<int> res(n); |
| for (int i = 0; i < n; ++i) |
| res[i] = i; |
| while (!q.empty()) { |
| int v = q.front(); |
| q.pop(); |
| |
| for (const auto &item: graph[v]) { |
| |
| if (--in_degree[item] == 0) q.push(item); |
| |
| if (quiet[res[v]] <= quiet[res[item]]) res[item] = res[v]; |
| } |
| } |
| |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int minimumTime(int n, vector<vector<int>> &relations, vector<int> &time) { |
| vector<int> in_degree(n + 1, 0); |
| vector<vector<int>> graph(n + 1); |
| for (const auto &item: relations) { |
| graph[item[0]].emplace_back(item[1]); |
| in_degree[item[1]]++; |
| } |
| |
| queue<int> q; |
| for (int i = 1; i <= n; ++i) |
| if (in_degree[i] == 0) |
| q.push(i); |
| |
| |
| vector<int> cost(time); |
| int res = 0; |
| while (!q.empty()) { |
| int v = q.front(); |
| q.pop(); |
| res = max(res, cost[v - 1]); |
| for (const auto &item: graph[v]) { |
| if (--in_degree[item] == 0) q.push(item); |
| |
| cost[item - 1] = max(cost[item - 1], time[item - 1] + cost[v - 1]); |
| } |
| } |
| |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int maximumInvitations(vector<int> &favorite) { |
| |
| int n = favorite.size(); |
| vector<int> in_degree(n, 0); |
| for (const auto &item: favorite) |
| in_degree[item]++; |
| |
| |
| vector<int> deep(n, 0); |
| |
| queue<int> q; |
| for (int i = 0; i < n; ++i) |
| if (in_degree[i] == 0) |
| q.push(i); |
| |
| |
| while (!q.empty()) { |
| int v = q.front(); |
| q.pop(); |
| int nxt = favorite[v]; |
| if (--in_degree[nxt] == 0) q.push(nxt); |
| |
| deep[nxt] = max(deep[nxt], deep[v] + 1); |
| } |
| |
| int sumOfSmallRing = 0; |
| int maxLargeRing = 0; |
| for (int i = 0; i < n; ++i) { |
| |
| if (in_degree[i] == 0) continue; |
| in_degree[i] = 0; |
| |
| int ringLen = 1; |
| |
| int nxt = favorite[i]; |
| while (in_degree[nxt] != 0) { |
| ringLen++; |
| in_degree[nxt] = 0; |
| nxt = favorite[nxt]; |
| } |
| if (ringLen == 2) { |
| |
| |
| sumOfSmallRing += deep[i] + deep[favorite[i]] + 2; |
| } else { |
| |
| maxLargeRing = max(maxLargeRing, ringLen); |
| } |
| } |
| return max(sumOfSmallRing, maxLargeRing); |
| } |
| }; |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18410625
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步