bzoj3573: [Hnoi2014]米特运输

18 篇文章 0 订阅

看懂了题目就A了一半。。。

大意是这样的,给一棵以1为根的树,求最少修改几个点的容量后,使得除根节点外所有节点为父亲容量/父亲的儿子个数。

因为1个节点确定,所有节点都确定了,不妨对每个点求出它不修改时根节点的容量,Hash一下就可以了。(貌似自然溢出会WA,可能我写炸了吧)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 500005
#define A 1000000007
#define B 20000909
using namespace std;
int n,a[N],x,y,first[N],next[N<<1],to[N<<1],l,Ans,d[N],fa[N];
struct Hash{ll a,b;}k[N];
bool operator<(Hash x,Hash y)
{
	if (x.a!=y.a) return x.a<y.a;
	return x.b<y.b;
}
bool operator==(Hash x,Hash y)
{
	return x.a==y.a&&x.b==y.b;
}
int Re()
{
	char c=getchar();int x=0;
	while (c<'0'||c>'9') c=getchar();
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	return x;
}
void link(int x,int y)
{
	to[++l]=y;next[l]=first[x];first[x]=l;d[x]++;
	to[++l]=x;next[l]=first[y];first[y]=l;d[y]++;
}
void dfs(int x)
{
	Hash t;
	t.a=k[x].a*d[x]%A;
	t.b=k[x].b*d[x]%B;
	for (int i=first[x];i;i=next[i])
		if (to[i]!=fa[x]) fa[to[i]]=x,k[to[i]]=t,dfs(to[i]);
	k[x]=(Hash){k[x].a*a[x]%A,k[x].b*a[x]%B};
}
int main()
{
	n=Re();
	for (int i=1;i<=n;i++)
		a[i]=Re();
	for (int i=2;i<=n;i++)
		x=Re(),y=Re(),link(x,y),d[i]--;
	k[1]=(Hash){1,1};dfs(1);
	sort(k+1,k+n+1);
	for (int i=1,j;i<=n;i=j+1)
	{
		for (j=i;j<n&&k[j+1]==k[i];j++);
		Ans=max(Ans,j-i+1);
	}
	printf("%d\n",n-Ans);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值