提供一种DP的思路;
dp[i][0/1]表示第i个结点染色不染色/染色的最大的染色数量。
那么对于dp[i][0]来说就是它的子节点的染色最大树量的和,dp[i][1]则需要再来一轮循环,统计某个子节点与父节点一起染色的最大值。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector a(n + 1, 0);
for (int i = 1; i <= n; i ++) {
cin >> a[i];
}
vector g(n + 1, vector<int>());
for (int i = 1; i < n; i ++) {
int u, v;
cin >> u >> v;
g[u].emplace_back(v);
g[v].emplace_back(u);
}
vector dp(n + 1, array<int, 2>());
auto dfs = [&]( auto && self, int u, int fa) -> void{
for (const auto &v : g[u]) {
if (v == fa) continue;
self(self, v, u);
dp[u][0] += max(dp[v][0], dp[v][1]);
}
for (const auto &v : g[u]) {
if (v == fa)continue;
i64 x = sqrt(1LL * a[u] * a[v]);
if (x * x == 1LL * a[u] * a[v]) {
dp[u][1] = max(dp[u][1], dp[u][0] - max(dp[v][0], dp[v][1]) + dp[v][0] + 2);
}
}
};
dfs(dfs, 1, -1);
cout << max(dp[1][0], dp[1][1]) << "\n";
return 0;
}

京公网安备 11010502036488号