题目:
输入:
输出:
样例:
思路:
这题的本质显然是树搜索问题。建模后用深度优先搜索(DFS) 算法解决。难点在于如何建模。由题意可得,不会经过一个点两次则图中必然没有环,又由于只有一个节点的父亲节点为空(也即-1), 则必然是一棵树。将dfs的含义定义为以从树的根节点能获得的最大的物品价值,在求解这个问题时会遍历所有树上的节点,相当于枚举了以任意节点为起点获得的最大值,因此在每个节点return前对最终答案进行更新即可。
代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int dfs(int id, vector<vector<int>> &G, vector<int> &v, vector<int>&a) { //由于需要记录每一个节点向下的数据,按引用传递a以便修改
int idMost = 0;
for (int j : G[id]) {
idMost = max(dfs(j, G, v, a), idMost);
}
a[id] = v[id] + idMost;
return a[id];
}
int main() {
int N; //方块个数
cin >> N;
vector<vector<int>> G(N); //G[i]是编号为i的节点的子节点(i方块所能进入的方块)
vector<int> v(N); //v[i]是第i个方块的value
int root; //记录作为根节点的方块编号
for (int i = 0; i < N; i++) {
int id, parent_id, value;
cin >> id >> parent_id >> value;
v[id] = value;
if (parent_id == -1) { root = id; } //更新root
else G[parent_id].push_back(id); //parent_id节点的所有子节点
}
vector<int> a(N); //f[i]表示以节点i为初始位置遍历时的最大路径加权
dfs(root,G,v,a); //dfs搜索
auto maxPosition = max_element(a.begin(), a.end()); // 返回的是最大值迭代器所在的位置
cout << *maxPosition << endl;
return 0;
}
简化为lamda函数形式:
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
int main() {
int N; //方块个数
cin >> N;
vector<vector<int>> G(N); //G[i]是编号为i的节点的子节点(i方块所能进入的方块)
vector<int> v(N); //v[i]是第i个方块的value
int root; //记录作为根节点的方块编号
for (int i = 0; i < N; i++) {
int id, parent_id, value;
cin >> id >> parent_id >> value;
v[id] = value;
if (parent_id == -1) { root = id; } //更新root
else G[parent_id].push_back(id); //parent_id节点的所有子节点
}
vector<int> a(N); //f[i]表示以节点i为初始位置遍历时的最大路径加权
function<int(int)> dfs = [&](int i) {
int valMore = 0;
for (int j : G[i]) valMore = max(dfs(j), valMore);
a[i] = v[i] + valMore;
return a[i];
};
dfs(root); //dfs搜索,注意需要记录每一个节点向下的数据
auto maxPosition = max_element(a.begin(), a.end()); // 返回的是最大值迭代器所在的位置
cout << *maxPosition << endl;
return 0;
}