[51nod1673]树有几多愁

2023-11-24 22:59
文章标签 树有 几多 51nod1673

本文主要是介绍[51nod1673]树有几多愁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  lyk有一棵树,它想给这棵树重标号。
  重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号。
  这棵树的烦恼值为所有叶子节点的值的乘积。
  lyk想让这棵树的烦恼值最大,你只需输出最大烦恼值对1e9+7取模后的值就可以了。
  注意一开始1号节点为根,重标号后这个节点仍然为根。

  update:数据保证叶子节点个数<=20。

 Input
  第一行一个数n(1<=n<=100000)。
  接下来n-1行,每行两个数ai,bi(1<=ai,bi<=n),表示存在一条边连接这两个点。
Output
  一行表示答案

 

  显然小的编号应该丢给深度大的点,也就是说,从小到大确定编号的话,一个点子树内的所有其他点都被确定了之后 这个点才会(并且一定要)被确定。

  但具体叶子之间谁先谁后还是有影响的。。。

  就直接状压一波,f[i]表示已经确定编号的叶子的状态为i时的最大烦恼值(叶子只要给了编号,对烦恼值的贡献就确定下来了)。

  先把原树上一些没用的点删掉,只保留叶子和有多个儿子的节点(其实就是虚树...)

  每次枚举一个状态的时候,直接在虚树上暴力求出到底哪些点的编号已被确定了。这样就知道下一个叶子的编号是什么...再枚举下一个确定的是哪个叶子并转移就好了。

  因为答案很大,比较方案优劣的时候可以用double。。

  时间复杂度O(2^n*虚树节点数),虚树节点数大概就40个左右吧?

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstdlib>
 8 #include<bitset>
 9 //#include<ctime>
10 #define ll long long
11 #define ull unsigned long long
12 #define ui unsigned int
13 #define d double
14 //#define ld long double
15 using namespace std;
16 const int maxn=102333,modd=1000000007;const d eps=1e-7;
17 struct zs{int too,pre;}e[maxn<<1],E[maxn];int tot,last[maxn],TOT,LAST[maxn];
18 int sz[maxn];bool leaf[maxn],gg[maxn];
19 d f[(1<<20)+23333];int g[(1<<20)+23333];
20 int i,j,k,n,m;
21 
22 int ra;char rx;
23 inline int read(){
24     rx=getchar(),ra=0;
25     while(rx<'0')rx=getchar();
26     while(rx>='0')ra=ra*10+rx-48,rx=getchar();return ra;
27 }
28 
29 
30 void dfs(int x,int fa){
31     int son=0;
32     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa)
33         dfs(e[i].too,x),son++,sz[x]+=sz[e[i].too];
34     leaf[x]=!son,sz[x]++;
35     gg[x]=!leaf[x]&&son==1;
36 }
37 
38 inline void insert(int a,int b){
39     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
40     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
41 }
42 inline void ins(int a,int b){
43     E[++TOT].too=b,E[TOT].pre=LAST[a],LAST[a]=TOT;
44 }
45 int a[maxn],cnt;int pos[23],LEAF;int sz1[maxn],got[maxn];int num[maxn];
46 void dfs2(int x,int _fa,int tmp){
47     if(!gg[x]){
48         a[++cnt]=x,num[cnt]=tmp;
49         if(leaf[x])pos[LEAF++]=cnt;
50         if(_fa)ins(_fa,cnt);
51         _fa=cnt,tmp=0;
52     }
53     for(int i=last[x];i;i=e[i].pre)if(sz[e[i].too]<sz[x])dfs2(e[i].too,_fa,tmp+1);
54 }
55 int main(){
56     n=read();
57     for(i=1;i<n;i++)insert(read(),read());
58     dfs(1,0),dfs2(1,0,1);
59     
60 //    for(i=1;i<=cnt;i++)printf("  %d",num[i]);puts("");
61 //    for(i=0;i<LEAF;i++)printf("    %d",pos[i]);puts("");
62     
63     for(j=0;j<LEAF;j++)sz1[pos[j]]=1;
64     for(j=cnt;j;j--)for(k=LAST[j];k;k=E[k].pre)sz1[j]+=sz1[E[k].too];
65     
66     f[0]=g[0]=1;int mx=1<<LEAF,st,tozt,tog;d tof;register int j,k;
67     for(i=0;i<mx-1;i++){
68         memset(got+1,0,cnt<<2);
69         for(j=0;j<LEAF;j++)got[pos[j]]=(i&(1<<j))>0;
70         
71         for(j=cnt,st=1;j;st+=got[j]==sz1[j]?num[j]:0,j--)
72             for(k=LAST[j];k;k=E[k].pre)got[j]+=got[E[k].too];
73         tof=f[i]*st,tog=1ll*g[i]*st%modd;
74 //        printf("zt:%d   st:%d\n",i,st);
75         for(j=0;j<LEAF;j++)if(!(i&(1<<j))&& f[tozt=(i|(1<<j))]<tof )f[tozt]=tof,g[tozt]=tog;
76     }printf("%d\n",g[mx-1]);
77 }
View Code

 

转载于:https://www.cnblogs.com/czllgzmzl/p/5956412.html

这篇关于[51nod1673]树有几多愁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/422693

相关文章

B+ 树和B树有什么区别,数据库索引为什么用B+树

B树(B-tree)和B+树(B+ tree)是两种常见的自平衡搜索树数据结构,通常用于数据库索引以及文件系统等领域。 它们在设计上有一些区别,下面是它们的主要差异以及为什么数据库索引通常使用B+树: 结构差异: B树:B树是一种平衡多路搜索树,其中每个节点包含一个有序数组。节点内的关键字按升序排列,并且每个节点通常有多个子节点。B树的特点是每个节点都包含数据,而不仅仅是叶子节点。 B+树

百度云管家提速试用手记 - 几多欢喜几多愁

百度云管家提速试用手记 - 几多欢喜几多愁 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。

阿里嘎几多

定义目录标题) 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的界面设计

51Nod-1673-树有几多愁

ACM模版 描述 题解 真的感觉这个题好难,看了官方题解也不知道怎么搞,又找了一下代码,稍微懂了一些……总得来说,这个题就是 dp dp(树归、状压) + 贪心,贴一下官方题解吧……我也说不好。真废…… 代码 #include <cstdio>#include <vector>#include <algorithm>#include <cmath>#include <c

Java架构师必备技能—JVM系列:问君能有几多愁,系统宕机重启流

上回说到《不识JVM真面目,只缘身在增删查改中》 讲述了一些有关于Jvm,线程,栈的有关技术知识,还有两个关于JVM的面试题: JVM什么情况下会发生栈内存溢出?JVM中一次完整的GC流程是怎样的? GC——垃圾回收 完整意味着有多种情况 今天就接着将视频内容介绍完 可达性分析算法——GC Roots 判断对象的存活 在Java, 可作为GC Roots的对象包括: 虚拟机栈(本

设计道路多美好,不知前方几多愁? ——UI设计秘诀之iPad篇

iPad划时代地将我们带入了平板电脑时代,对于传统的移动终端的设计师而言,一个拥有更大的触摸屏幕,更大空间的舞台展现在大家面前,看上去一切都是那么的美好。然而如何在iPad上设计出优秀的用户界面?相信对于设计师们的挑战与忧愁远不止屏幕放大那么简单。 1.模拟真实,沉浸其中 大的屏幕、可以触摸的操作、支持多种手势…这一切条件都为让用户能沉浸于你的设计中提供了条件,那么如

妈妈的爱无限大,儿子的回报能有几多?

刚出生的时候 妈妈说 等你长大了 妈妈就轻松了 等上了初中 妈妈说 等你考上高中 妈妈就轻松了 等我考上了高中 妈妈又说 等你上了大学 妈妈就轻松了 ,待我考上了大学后 妈妈说 等你毕业了找到好工作了 妈妈就可以享福了 等我毕业了 找到了工作 妈妈说 等你成家了 妈妈就轻松了 ,等我成家了 妈妈说 等帮你把孙子带大妈妈就可以享福了,现在我想说 妈你可以享福了 可是您还听的到吗?

面试官: B 树和 B+ 树有什么区别?

问各位小可爱一个问题:MySQL 中 B 树和 B+ 树的区别? 请自己先思考5秒钟,看看是否已经了然如胸?   好啦,时间到! B 树和 B+ 树是两种数据结构,构建了磁盘中的高速索引结构,因此不仅 MySQL 在用,MongoDB、Oracle 等也在用,基本属于数据库的标配常规操作。 数据库要经常和磁盘与内存打交道,为了提升性能,通常需要自己去构建类似文件系统的结构。今天主要来看