拓扑排序(toposort)
杂物(拓扑排序)
前置知识
有向无环图(DAG):没有环的有向图。
对于DAG,在有的时候,对于一个节点的信息的计算,需要确保与之相连的点的信息全部被计算,这时就需要用到拓扑排序。
本质是确保DAG上的点的计算顺序而非对数列排序。
队列实现拓扑排序过程
- step1:讲入度为0的点插入队列
- step2:取出队头
,遍历所有t能到达的点 。 - step3:对于每一个
,维护其节点信息,同时使它入度-1,以完成删边操作。 - step4:当
入度为 时,插入队列。 - step5:跳转到step2。
注意
本题维护的节点信息是dp[i]
,表示第i个杂物的最早完成时间。(有动态规划那味了)
dp[i]
是由它的前驱节点转移过来的。
#include<bits/stdc++.h> #define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define bug(x) cout<<#x<<"=="<<x<<endl; #define endl "\n" #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int, int> PII; const int INF = 0x3f3f3f3f; const int inf = 0xc0c0c0c0; const int N = 1e4 + 10; vector<int> g[N]; int n; int len[N]; int pre; int rd[N]; queue<int> q; int dp[N]; int main() { ios; cin >> n; for (int i = 1; i <= n; i++) { int c; cin >> c; cin >> len[c]; while (cin >> pre && pre) { g[pre].push_back(c); rd[c]++; } } for (int i = 1; i <= n; i++) { if (rd[i] == 0) { q.push(i); dp[i] = len[i]; } } while (!q.empty()) { auto t = q.front(); q.pop(); for (auto v : g[t]) { dp[v] = max(dp[v], dp[t] + len[v]); rd[v]--; if (rd[v] == 0) q.push(v); } } int ans = 0; for (int i = 1; i <= n; i++) { ans = max(ans, dp[i]); } cout << ans << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!