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

2 years ago
#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
*/
/**
1DAG
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;
}