描述
壮壮是一个爱探险的孩子,一天他爬上了一座山,然后利用先进的遥感技术了解到了整座山的地形和内部构造。他发现,这座山一共有N个山洞和M个暗道,每一个山洞里都有宝藏,第i个山洞里有无限份价值为Ai的宝藏,壮壮经过山洞i就会领取山洞i中的一份宝藏(每次经过都能领取一份).
每一个暗道都连通两个山洞,第i个暗道连通了山洞Xi和Yi,壮壮可以穿过暗道i从山洞Xi到达Yi,但是不可以穿过暗道i从山洞Yi到达Xi,但无论怎么穿过暗道i都要耗费一定的体力值Zi。
得知这些探洞信息后,壮壮马上开始准备去寻宝藏,已知壮壮的体力值上限为T,他最多只能耗费T的体力值,壮壮可以从任意一个山洞开始他的探索,但是只能穿过暗道去到别的山洞。
他每到达一个山洞,都会领取山洞中的一份宝藏,他想知道他最多可以获得的宝藏价值之和是多少?
输入
第一行三个整数N、M和T,分别代表山洞的数量、暗道的数量和体力值上限。
第二行N个整数,第i个数是Ai,表示山洞i中的宝藏价值。
接下来M行:每行三个整数Xi、Yi和Zi,分别代表暗道i连接的两个山洞的编号和穿过这个暗道所要耗费的体力值。
输出
输出一个整数,表示耗费的体力值不超过T时,壮壮最多能获得的宝藏价值之和。
输入样例 1
5 6 10
5 5 6 3 2
2 5 1
1 3 6
3 4 2
4 5 3
4 5 10
3 5 10
输出样例 1
14
提示
样例中每一个点、边的情况如图所示,最优的走法是1->3->4
对于30%的数据,1≤N≤10,1≤M≤20;
对于50%的数据,1≤N≤20,1≤M≤50;
对于70%的数据,1≤N≤150,1≤M≤500;
对于100%的数据,1≤Zi,T≤500,1≤N,Xi,Yi≤1000,1≤M,Ai≤10000
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int from, to, cost;
};
int main() {
int N, M, T;
cin >> N >> M >> T;
vector<int> treasure(N);
for (int i = 0; i < N; ++i) {
cin >> treasure[i];
}
vector<Edge> edges(M);
for (int i = 0; i < M; ++i) {
cin >> edges[i].from >> edges[i].to >> edges[i].cost;
--edges[i].from;
--edges[i].to;
}
vector<vector<int>> dp(N, vector<int>(T + 1, 0));
for (int i = 0; i < N; ++i) {
dp[i][0] = treasure[i];
}
for (int j = 1; j <= T; ++j) {
for (const auto& e : edges) {
if (j >= e.cost) {
int new_cost = dp[e.from][j - e.cost] + treasure[e.to];
dp[e.to][j] = max(dp[e.to][j], new_cost);
}
}
}
int max_treasure = 0;
for (int i = 0; i < N; ++i) {
max_treasure = max(max_treasure, *max_element(dp[i].begin(), dp[i].end()));
}
cout << max_treasure << endl;
return 0;
}