You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
int n; //必须完成的杂务的数目
int x; //工作序号
int y; //一些必须完成的准备工作
int ans; //最终结果
int a[N]; //完成工作所需要的时间a[x]
int f[N]; //这个结点的最长时间
vector<int> edge[N]; //出边链表
/**
测试数据:
7
1 5 0
2 2 1 0
3 3 2 0
4 6 1 0
5 1 2 4 0
6 8 2 4 0
7 4 3 5 6 0
答案:
23
*/
/**
* 功能计算x号任务的最短完成时间
* @param x
* @return
*/
/**
总结:
1、创建DAG的通用办法
2、注意谁是出发点谁是终止点
3、深度优先搜索的应用万能的魔法函数
4、记忆化搜索优化深度优先搜索
5、计算的是每个结点出发的最长链(自顶向下)
*/
int dfs(int x) {
//记忆化搜索,防止重复计算
if (f[x]) return f[x];
//找到连接到这个结点的边的最长的一个
for (int i = 0; i < edge[x].size(); i++)
f[x] = max(f[x], dfs(edge[x][i]));
//加上本号任务的时长
f[x] += a[x];
//返回最短时间
return f[x];
}
int main() {
//创建DAG的标准套路
//需要完成的杂务的数目
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x >> a[x]; //完成工作所需要的时间len[x],注意此处书中写的是len[i],也是可以AC的
// 原因是默认输入就是123...这样的输入,没有乱序输入。其实,如果没有乱序输入,
// 这个cin>>x就是无用的因为x肯定是等于i的。
while (cin >> y) {
//需要完成的准备工作
if (!y) break; //由一个数字0结束
//前序啊!注意,这里是前序是谁!!!由谁到谁有一条有向边!!!
edge[y].push_back(x); //这里要注意!!!! 是y向x有一条有向边描述的是y是x的前序工作 !!!!
}
}
//以上代码建图完毕!!!!
//对于每项任务,分别计算最长工作时长,取最大值,就是最后的答案
for (int i = 1; i <= n; i++) ans = max(ans, dfs(i));
//输出大吉
cout << ans << endl;
return 0;
}