css實現右上角角標
阿新 • • 發佈:2021-01-18
既然是工作之間的相互關係,那麼一定是有向無環圖,所以可以用記憶化來做
狀態定義:\(f[i]\)表示從\(i\)號工作開始完成後續所有工作的安排方法集合,儲存能夠完成\(i\)號及其後續所有工作所需的最短時間
狀態轉移:\(f[i] = w[i] + max\{f[j_1], f[j_2],...f[j_k],...\},\)其中\(i\)是\(j_k\)的直接準備工作(即DAG上存在\(i\to j_k\)的邊)
初始條件:對於沒有後續的結點\(k\),\(f[k] = w[k]\)
答案:\(max\{f[i]\},i\)為所有的無前驅的結點
鄰接表存圖複雜度:\(O(N + E)\)
#include<iostream> #include<cstring> using namespace std; const int N = 10010, M = 1000010; int h[N], e[M], ne[M], idx; int w[N], in[N], f[N]; int n; void add(int a, int b){ e[idx] = b, ne[idx] = h[a], h[a] = idx ++; } int dfs(int u){ if(f[u]) return f[u]; f[u] = w[u]; for(int i = h[u]; i != -1; i = ne[i]){ int j = e[i]; f[u] = max(f[u], w[u] + dfs(j)); } return f[u]; } int main(){ memset(h, -1, sizeof h); cin >> n; for(int i = 1; i <= n; i ++){ int num, len; cin >> num >> len; w[num] = len; int pre; while(cin >> pre, pre) add(pre, num), in[num] ++; } int res = 0; for(int i = 1; i <= n; i ++) if(in[i] == 0) res = max(res, dfs(i)); cout << res << endl; return 0; }