D 小美的樹上染色
題目描述
小美拿到了一棵樹,每個節點有一個權值。初始每個節點都是白色。
小美有若干次操作,每次操作可以選擇兩個相鄰的節點,如果它們都是白色且權值的乘積是完全平方數,小美就可以把這兩個節點同時染紅。
小美想知道,自己最多可以染紅多少個節點?
輸入描述
第一行輸入一個正整數\(n\),代表節點的數量。
第二行輸入\(n\)個正整數\(a_i\),代表每個節點的權值。
接下來的\(n-1\)行,每行輸入兩個正整數\(u,v\),代表節點\(u\)和節點\(v\)有一條邊連線。
\(1\leq n \leq 10^5\)
\(1\leq a_i \leq 10^9\)
\(1\leq u,v \leq n\)
輸出描述
輸出一個整數,表示最多可以染紅的節點數量。
解題思路
直接按照題意模擬,dfs暴力搜尋即可
程式碼實現
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
vector<int> g[N];
int st[N],w[N];
int ans;
void dfs(int u,int fa){
for(auto x:g[u]){
if(x==fa){
continue;
}
dfs(x,u);
if((int)sqrt(w[u]*w[x])*(int)sqrt(w[u]*w[x])==w[u]*w[x]&&(!st[x]&&!st[u])){//判斷染色條件
ans+=2;
st[x]=1;
st[u]=1;
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>w[i];//權值
}
for(int i=0;i<n-1;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,-1);
cout<<ans;
return 0;
}