提供一种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; }