小美拿到了一棵树,每个节点有一个权值。初始每个节点都是白色。 小美有若干次操作,每次操作可以选择两个相邻的节点,如果它们都是白色且权值的乘积是完全平方数,小美就可以把这两个节点同时染红。 小美想知道,自己最多可以染红多少个节点?
区块链毕设网qklbishe.com为您提供问题的解答
小美拿到了一棵树,每个节点有一个权值。初始每个节点都是白色。
小美有若干次操作,每次操作可以选择两个相邻的节点,如果它们都是白色且权值的乘积是完全平方数,小美就可以把这两个节点同时染红。
小美想知道,自己最多可以染红多少个节点?
从叶节点考虑,拓扑排序
#include<iostream> #include<vector> #include<queue> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; inline bool check(int x,int y){ ll res=(ll)x*y,z=(ll)sqrt(res); return z*z==res; } int solve(int n){ int u,v; vector<int> value(n+1),degrees(n+1),flag(n+1),color(n+1); vector<vector<int>> edges(n+1); for(int i=1;i<=n;i++){ cin>>value[i]; } for(int i=1;i<n;i++){ cin>>u>>v; edges[u].push_back(v); edges[v].push_back(u); degrees[u]++,degrees[v]++; } queue<int> q; for(int i=1;i<=n;i++){ if(degrees[i]==1){ q.push(i); } } int ans=0; while(!q.empty()){ int top=q.front(); q.pop(); flag[top]=1; for(auto& p:edges[top]){ if(!flag[p]){ if(!color[top]&&!color[p]&&check(value[top],value[p])){ color[top]=1,color[p]=1; ans+=2; } if(--degrees[p]==1){ q.push(p); } } } } return ans; } //优先考虑叶节点,拓扑排序 int main() { int n; while(cin>>n){ cout<<solve(n)<<endl; } } // 64 位输出请用 printf("%lld")
17:14
以上就是关于问题小美拿到了一棵树,每个节点有一个权值。初始每个节点都是白色。 小美有若干次操作,每次操作可以选择两个相邻的节点,如果它们都是白色且权值的乘积是完全平方数,小美就可以把这两个节点同时染红。 小美想知道,自己最多可以染红多少个节点?的答案
欢迎关注区块链毕设网-
专业区块链毕业设计成品源码,定制。
区块链NFT链游项目方科学家脚本开发培训