(知道题目来源的大佬们别声张,蒟蒻也不清楚版权之类会不会有问题之类的怕惹麻烦 QwQ)
大致的思路如下:
vector<int> zero 存储它哪些儿子的状态是 0。zero 中添加 x。然后遍历 x 的 zero,将这些儿子节点的状态设为 1,添加进优先队列。然后清空 x 的 zero。zero 删除 x,原因在下一点。前 10 个点都对了,但是 Hack 数据全部 WA。求调。
#include <iostream>
#include <vector>
#include <queue>
struct node // 节点信息
{
int w, fa; // w 为价值, fa 为父亲编号
bool s; // 状态
std::vector<int> son, zero; // son 为所有儿子的编号 (邻接表), zero 为思路中第二点
};
node t[200005];
std::priority_queue<std::pair<int, int>> pq; // 第一点
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n, m;
std::cin >> n >> m;
for (int i = 1; i < n; i++)
{
int u, v;
std::cin >> u >> v;
t[u].son.push_back(v);
t[v].fa = u;
}
for (int i = 1; i <= n; i++)
std::cin >> t[i].w;
for (int i = 1; i <= n; i++)
{
std::cin >> t[i].s;
// 初始化
if (t[i].s == 1)
pq.push({t[i].w, i});
else
t[t[i].fa].zero.push_back(i);
}
std::cout << pq.top().first << "\n";
for (int i = 1; i <= m; i++)
{
int x;
std::cin >> x;
if (t[x].s == 0) // 第四点
{
t[x].s = 1;
pq.push({t[x].w, x});
}
else // 第三点
{
t[x].s = 0;
t[t[x].fa].zero.push_back(x);
for (auto j : t[x].zero)
if (t[j].s == 0)
{
t[j].s = 1;
pq.push({t[j].w, j});
}
t[x].zero.clear();
}
while (t[pq.top().second].s == 0) // 第五点
pq.pop();
std::cout << pq.top().first << "\n";
}
return 0;
}