拓扑排序(toposort)

杂物(拓扑排序)

前置知识
有向无环图(DAG):没有环的有向图。
对于DAG,在有的时候,对于一个节点的信息的计算,需要确保与之相连的点的信息全部被计算,这时就需要用到拓扑排序
本质是确保DAG上的点的计算顺序而非对数列排序。
队列实现拓扑排序过程

  • step1:讲入度0的点插入队列
  • step2:取出队头t,遍历所有t能到达的点v
  • step3:对于每一个v,维护其节点信息,同时使它入度-1,以完成删边操作
  • step4:当v入度0时,插入队列。
  • 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;
}
posted @   csai_H  阅读(119)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示