POJ-1949(DAG最長路徑)
阿新 • • 發佈:2019-02-04
所有任務合起來構成一個DAG,因為任務可以並行,所以從無前驅的節點到無後繼的節點的所有任務路徑中,最耗時的那一條就是所需要的總時間,因為這樣的搜尋中已經考慮了一個任務所有可能的開始時間。
樹形DP是DFS的方式,實際上由於我們的最終目的是想找到最長路徑,還可以採取類似SPFA的思想進行拓撲圖的遍歷#include <cstdio> #include <cstring> #include <vector> using namespace std; int N, c[10005] = {0}; int f[10005]; vector<int> ch[10005]; int dp(int x) { if(f[x]) return f[x]; const vector<int>& v = ch[x]; for(int i = 0; i < v.size(); ++i){ f[x] = max(f[x], dp(v[i])); } f[x] += c[x]; return f[x]; } int main() { int i, k, p; while(~scanf("%d", &N)){ //initialize memset(f, 0, (N + 1) << 2); for(i = 0; i <= N; ++i) ch[i].clear(); //input for(i = 1; i <= N; ++i){ scanf("%d", c + i); scanf("%d", &k); if(k == 0){ ch[0].push_back(i); continue; } while(k--){ scanf("%d", &p); ch[p].push_back(i); } } //dp printf("%d\n", dp(0)); } return 0; }
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; int N, c[10005]; int f[10005]; vector<int> ch[10005]; queue<int> q; bool inq[10005]; int bfs() { memset(inq + 1, false, N); int res = 0; q.push(0); while(!q.empty()){ int x = q.front(); q.pop(); inq[x] = false; const vector<int>& v = ch[x]; for(int i = 0; i < v.size(); ++i){ int y = v[i]; if(f[y] >= f[x] + c[y]) continue; f[y] = f[x] + c[y]; if(ch[y].empty()) res = max(res, f[y]); else if(!inq[y]){ q.push(y); inq[y] = true; } } } return res; } int main() { int i, k, p; while(~scanf("%d", &N)){ //initialize memset(f, 0, (N + 1) << 2); for(i = 0; i <= N; ++i) ch[i].clear(); //input for(i = 1; i <= N; ++i){ scanf("%d", c + i); scanf("%d", &k); if(k == 0){ ch[0].push_back(i); continue; } while(k--){ scanf("%d", &p); ch[p].push_back(i); } } //bfs printf("%d\n", bfs()); } return 0; }