洛谷 P3237 [HNOI2014]米特运输
get到新技能当然要来记录一下辣
题意:给一棵树,每个点有一个权值,要求同一个父亲的儿子的权值全部相同,父亲的取值必须是所有儿子的权值和,求最少的修改数量
sol:自己瞎鸡巴yy一下可以发现,如果根节点(当做1来算)权值确定,整棵树所有点的权值也都确定了,再一想,其实只要有一个点的权值确定,那么根节点的权值也必然确定了 配个图吧qaq(没事找事)
于是发现对于每个点的权值,求出其对应的根节点的权值,找到出现次数最多的,就可以知道答案了啊
但是全部乘起来显然会爆蛋,看了fks大佬的blog知道了还可以用log,因为log(a*b)=log(a)+log(b),技能get,实现不是很难。
#include <cmath> #include <cstdio> #include <vector> #include <algorithm> using namespace std; const int N=500005;const double eps=1e-8; int n; double v[N],f[N]; vector<int>G[N]; inline void dfs(int x,double sum) { int i; f[x]=(double)sum+log(v[x]); for(i=0;i<G[x].size();i++) { dfs(G[x][i],sum+(double)log(G[x].size())); } } int main() { int i,x,y,re=1,tmp=1; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%lf",&v[i]); for(i=1;i<n;i++) { scanf("%d%d",&x,&y); G[x].push_back(y); }dfs(1,(double)(1.00)); sort(f+1,f+n+1); for(i=2;i<=n;i++) { if(f[i]-f[i-1]<eps)tmp++,re=max(re,tmp);else tmp=1; }printf("%d\n",n-re); }
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!