拓扑排序(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;
}

浙公网安备 33010602011771号