POJ-1949(DAG最长路径)

来源:互联网 发布:好看的网络剧穿越剧 编辑:程序博客网 时间:2024/06/03 17:59

题目:http://poj.org/problem?id=1949

所有任务合起来构成一个DAG,因为任务可以并行,所以从无前驱的节点到无后继的节点的所有任务路径中,最耗时的那一条就是所需要的总时间,因为这样的搜索中已经考虑了一个任务所有可能的开始时间。


#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)){//initializememset(f, 0, (N + 1) << 2);for(i = 0; i <= N; ++i) ch[i].clear();//inputfor(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);}}//dpprintf("%d\n", dp(0));}return 0;}
树形DP是DFS的方式,实际上由于我们的最终目的是想找到最长路径,还可以采取类似SPFA的思想进行拓扑图的遍历


#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)){//initializememset(f, 0, (N + 1) << 2);for(i = 0; i <= N; ++i) ch[i].clear();//inputfor(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);}}//bfsprintf("%d\n", bfs());}return 0;}


0 0