【BZOJ】3573: [Hnoi2014]米特运输
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3573
屁话一堆,就是说:
1.一棵树中的每个点的每个儿子的权值之和要等于这个点的权值
2.一棵树中的每个点的每个儿子的权值相等。
所以,考虑确定一个点即确定的整个树的每个点的权值,但是我们受限于数据范围又不能枚举每一个点,所以枚举每一个点,考虑这个点的权值不变的话根节点的权值会是多少,这个是可以DP的,然后取个众数即可。
当然,权值过大所以需要一发HASH。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 501000 10 #define llg long long 11 #define md1 1000000007 12 #define md2 1000000009 13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 14 llg n,m,du[maxn],ans,tail,val[maxn]; 15 vector<llg>a[maxn]; 16 struct node 17 { 18 llg v1,v2; 19 }dl[maxn]; 20 21 bool cmp(const node a,const node&b) {if (a.v1==b.v1) return a.v2<b.v2;else return a.v1<b.v1;} 22 23 void init() 24 { 25 cin>>n; 26 for (llg i=1;i<=n;i++) scanf("%lld",&val[i]); 27 for (llg i=1;i<n;i++) 28 { 29 llg x,y; 30 scanf("%lld%lld",&x,&y); 31 a[x].push_back(y); du[x]++; 32 } 33 } 34 35 void dfs(llg x,llg fa,llg v1,llg v2) 36 { 37 llg w=a[x].size(); 38 dl[++tail].v1=(v1*val[x])%md1; 39 dl[tail].v2=(v2*val[x])%md2; 40 v1*=du[x],v2*=du[x]; 41 v1%=md1,v2%=md2; 42 for (llg i=0;i<w;i++) 43 { 44 dfs(a[x][i],x,v1,v2); 45 } 46 } 47 48 int main() 49 { 50 yyj("a"); 51 init(); 52 dfs(1,0,1,1); 53 sort(dl+1,dl+tail+1,cmp); 54 ans=n; 55 for (llg l=1;l<=tail;l++) 56 { 57 llg r=l; 58 while (r+1<=tail) 59 { 60 if (dl[l].v1!=dl[r+1].v1 || dl[l].v2!=dl[r+1].v2) break; 61 r++; 62 } 63 ans=min(ans,n-(r-l+1)); 64 } 65 cout<<ans; 66 return 0; 67 }
本文作者:xrdog
作者博客:http://www.cnblogs.com/Dragon-Light/
转载请注明出处,侵权必究,保留最终解释权!