Pro
Sol
好水的一道拓扑题……第一次打的时候可以说是随便打的……(逃。样例过了就交了,也没检查, 结果 分, 。改了改部分,加了点细节,就 了,总共耗时 分钟……(好长)
看到题目中存在先后关系,考虑拓扑,这样题目基本上很简单了。我们比平常的拓扑多维护了一个到目前为止已经的花费,因为这个是要更新答案的,所以,一定要取一个最大值(我不知道怎么了,这里都忘了)。还有,就是预处理的时候,把入读为 的点入队的时候,他们因为入度是 ,所以到目前为止的花费就是他们本身的花费。最后的答案就是各个拓扑后花费的最大值,这才是最短时间。
Code
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
int n , m , val[10005] , ind[10005] , before[10005] , ans = 0;
vector<int>e[10005];
queue<int>q;
int main() {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%d",&val[i]);
for(int i=1; i<=m; i++) {
int x , y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
ind[y]++;
}
for(int i=1; i<=n; i++)
if(!ind[i]) {
before[i] = val[i];
q.push(i);
}
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i=0; i<e[u].size(); i++) {
int v = e[u][i];
before[v] = max(before[v] , before[u] + val[v]);
ans = max(ans , before[v]);
ind[v]--;
if(!ind[v])
q.push(v);
}
}
printf("%d",ans);
return 0;
}