BZOJ3573: [Hnoi2014]米特运输
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3573
如果一个点的权值确定了,那么这棵树就确定了,我们对每一个点统计根节点是它的多少倍(太大于是开了log),然后找下众数就可以了。
#include<cstring> #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define maxn 500500 #define inf int(1e9) #define eps 1e-6 using namespace std; struct data{int obj,pre; }e[maxn*2]; double s[maxn]; int a[maxn],n,tot,head[maxn],d[maxn]; void insert(int x,int y){ e[++tot].obj=y; e[tot].pre=head[x]; head[x]=tot; } int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); } while (isdigit(ch)){ x=x*10+ch-'0'; ch=getchar(); } return x*f; } void dfs(int u,int fa){ for (int j=head[u];j;j=e[j].pre){ int v=e[j].obj; double now=(double)log(d[u]); if (v!=fa){ s[v]=s[u]+now; dfs(v,u); } } } int main(){ n=read(); rep(i,1,n) a[i]=read(); rep(i,1,n-1){ int x=read(),y=read(); insert(x,y); insert(y,x); d[x]++; d[y]++; } s[1]=log(1); rep(i,2,n) d[i]--; dfs(1,0); rep(i,1,n) s[i]=s[i]+(double)log(a[i]); sort(s+1,s+1+n); int tmp=1,ans=0; rep(i,2,n){ if (fabs(s[i]-s[i-1])<=eps) tmp++; else ans=max(ans,tmp),tmp=1; } ans=max(ans,tmp); printf("%d\n",n-ans); return 0; }