演算法提高課 拓撲排序專題(4/4)
阿新 • • 發佈:2022-05-24
AcWing 1191. 家譜樹
題意:
- 裸拓撲排序
AcWing 1192. 獎金
題意:
- 給定了\(m\)組要求\(a,b\),每次要求\(a\)的獎金比\(b\)的高,求出滿足所有要求的最小花費
- 每組要求看作\(b\rightarrow a\)的一條有向邊,令所有入度為0的點獎勵為最小值\(100\),然後拓撲排序的過程中不斷更新後繼節點的答案即可,為了滿足所有要求更新時取個\(max\)
- 可行性直接判斷最後拓撲排序後的陣列能否有\(n\)個數即可
#include <bits/stdc++.h> using namespace std; const int N = 10010; const int M = 20010; int head[N],to[M],nxt[M],tot,ind[N],award[N],n,m; void add(int u,int v) { to[++tot] = v,nxt[tot] = head[u],head[u] = tot; ind[v] ++; } bool toposort(vector<int>& vec) { queue<int>q; for(int i = 1;i <= n;i ++) { if(!ind[i]) { // cout << i << '\n'; award[i] = 100; q.push(i); } } // vector<int>ans; while(!q.empty()) { int u = q.front(); q.pop(); vec.push_back(u); for(int i = head[u];i;i = nxt[i]) { int v = to[i]; award[v] = max(award[v],award[u] + 1); if(--ind[v] == 0) { q.push(v); } } } // cout << vec.size() << '\n'; return vec.size() == n; } int main() { cin >> n >> m; while(m --) { int a,b; cin >> a >> b; add(b,a); } vector<int>ans; if(toposort(ans)) { int s = 0; for(auto i : ans) s += award[i]; cout << s << '\n'; } else { cout <<"Poor Xed\n"; } return 0; }