lyk有一棵树,它想给这棵树重标号。

重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号。
这棵树的烦恼值为所有叶子节点的值的乘积。
lyk想让这棵树的烦恼值最大,你只需输出最大烦恼值对1e9+7取模后的值就可以了。
注意一开始1号节点为根,重标号后这个节点仍然为根。
 
update:数据保证叶子节点个数<=20。
 
例如样例中,将1,2,3,4,5重标号为4,3,1,5,2,此时原来编号为4,5的两个叶子节点的值为3与1,这棵树的烦恼值为3。不存在其它更优解。
Input
第一行一个数n(1<=n<=100000)。
接下来n-1行,每行两个数ai,bi(1<=ai,bi<=n),表示存在一条边连接这两个点。
Output
一行表示答案
Input示例
5
1 2
2 4
2 3
3 5
Output示例
3
有一个贪心,就是把小的数尽可能放到靠近叶子节点的点,即从叶子到根逐渐变大
这样小的值就影响尽可能少的叶子
先可以把儿子数为1的点缩掉,这样缩完点后的新树只有40个点左右
我们设$f[S]$表示叶子状态为S的最大烦恼值
为1表示已经分配了值
现在我们要给i分配一个值,转移到S|(1<<i-1)
我们为了满足贪心原则,只有满足子树中叶子全部出现在了S中才有值
否则就会出现矛盾,即从i叶子到根会有比i小的情况
也就是算出这些子树的节点数id,然后叶子i填id+1,计入答案
由于取模不能判大小,所以在维护一个double比大小
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
struct Node
{
int next,to;
}edge[],edge2[];
int head[],num,num2,head2[],dep[],in[],b[],cnt,tot,n,l[],sz[],s[];
double f[<<];
lol g[<<],Mod=1e9+,w[],sum;
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void add2(int u,int v)
{
num2++;
edge2[num2].next=head2[u];
head2[u]=num2;
edge2[num2].to=v;
}
void dfs(int x,int pa,int tp)
{int i;
dep[x]=dep[pa]+;
if (in[x]!=)
{
b[++cnt]=x;w[cnt]=dep[x]-dep[tp];
if (tp!=x)
add2(tp,x);
tp=x;
}
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v!=pa) dfs(v,x,tp);
}
}
int main()
{int i,u,v,j,k;
cin>>n;
for (i=;i<=n-;i++)
{
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
in[u]++;in[v]++;
}
in[]=-;
dfs(,,);
for (i=;i<=n;i++)
if (in[i]==)
l[++tot]=i,sz[i]=;
for (i=cnt;i>=;i--)
{
for (j=head2[b[i]];j;j=edge2[j].next)
{
int v=edge2[j].to;
sz[b[i]]+=sz[v];
}
}
f[]=g[]=;
for (i=;i<(<<tot)-;i++)
{
for (j=;j<=cnt;j++)
s[b[j]]=;
for (j=;j<=tot;j++)
if (i&(<<j-))
s[l[j]]=;
lol id=;
for (j=cnt;j>=;j--)
{
for (k=head2[b[j]];k;k=edge2[k].next)
{
int v=edge2[k].to;
s[b[j]]+=s[v];
}
if (s[b[j]]==sz[b[j]]) id+=w[j];
}
double as=f[i]*id;
for (j=;j<=tot;j++)
if ((i&(<<j-))==&&as>f[i|(<<j-)])
f[i|(<<j-)]=as,g[i|(<<j-)]=g[i]*id%Mod;
}
cout<<g[(<<tot)-];
}

51nod 1673 树有几多愁的更多相关文章

  1. 51nod 1673 树有几多愁——虚树+状压DP

    题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1673 建一个虚树. 一种贪心的想法是把较小的值填到叶子上,这样一个小值限制到的 ...

  2. 51nod 1673 树有几多愁(链表维护树形DP+状压DP)

    题意 lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出 ...

  3. [51nod1673]树有几多愁

    lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出最大烦 ...

  4. 刷题总结——树有几多愁(51nod1673 虚树+状压dp+贪心)

    题目: lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输 ...

  5. 51nod1673 树有几多愁 - 贪心策略 + 虚树 + 状压dp

    传送门 题目大意: 给一颗重新编号,叶子节点的值定义为他到根节点编号的最小值,求所有叶子节点值的乘积的最大值. 题目分析: 为什么我觉得这道题最难的是贪心啊..首先要想到 在一条链上,深度大的编号要小 ...

  6. 题解 [51nod1673] 树有几多愁

    题面 解析 这题思路挺秒啊. 本麻瓜终于找了道好题了(还成功把ztlztl大仙拖下水了) 看到叶子节点数<=20就应该是状压啊. 然而DP要怎么写啊? 首先,考虑到编号肯定是从下往上一次增大的, ...

  7. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

  8. 51nod 1462 树据结构 | 树链剖分 矩阵乘法

    题目链接 51nod 1462 题目描述 给一颗以1为根的树. 每个点有两个权值:vi, ti,一开始全部是零. Q次操作: 读入o, u, d o = 1 对u到根上所有点的vi += d o = ...

  9. 51nod 1812 树的双直径 题解【树形DP】【贪心】

    老了-稍微麻烦一点的树形DP都想不到了. 题目描述 给定一棵树,边权是整数 \(c_i\) ,找出两条不相交的链(没有公共点),使得链长的乘积最大(链长定义为这条链上所有边的权值之和,如果这条链只有 ...

随机推荐

  1. 结合jenkins在Linux服务器搭建测试环境

    何时使用: 测试过程中我们需要持续构建一个软件项目,为避免重复的手动下载.解压操作,我们需要搭建一个能够自动构建的测试环境,当代码有更新时,测试人员只需点一下[构建]即可拉取最新的代码进行测试(也可设 ...

  2. C语言博客作业—函数嵌套调用

    一.实验作业 1.1 PTA题目:递归法对任意10个数据按降序排序 1.1.1设计思路 void sort(int a[],int n) { 定义整型循环变量i,中间变量temp,最小值min: 令m ...

  3. 转:运行page页面时的事件执行顺序及页面的回发与否深度了解

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  4. C++之异常捕获和处理

    一.简介   在C++语言中,异常处理包括:throw表达式,try语句块,一套异常类.其中,异常类用于在throw表达式和相关的catch子句之间传递异常的具体信息.exception头文件定义了最 ...

  5. Alpha冲刺Day4

    Alpha冲刺Day4 一:站立式会议 今日安排: 我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.完成了数据库管理员模块.因企业人员与第三方人员模块存在大量的一致性,故我们团 ...

  6. 《招一个靠谱的移动开发》iOS面试题及详解(上篇)

    以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...

  7. bzoj 4373 算术天才⑨与等差数列

    4373: 算术天才⑨与等差数列 Time Limit: 10 Sec  Memory Limit: 128 MBhttp://www.lydsy.com/JudgeOnline/problem.ph ...

  8. 集合Collection总览

    前言 声明,本文使用的是JDK1.8 从今天开始正式去学习Java基础中最重要的东西--->集合 无论在开发中,在面试中这个知识点都是非常非常重要的,因此,我在此花费的时间也是很多,得参阅挺多的 ...

  9. linux系统增加开机启动服务/应用

    操作 在/etc/init.d下新建示例脚本文件(customize.sh),该脚本会启动zookeeper服务.内容如下: #!/bin/sh /usr/local/zookeeper-/bin/z ...

  10. JAVA类的方法调用和变量(全套)

    一.类的分类: 1.普通类 2.抽象类(含有抽象方法的类) 3.静态类(不需要实例化,就可以使用的类) 二.方法的分类: 1.私有方法(只有类的内部才可以访问的方法) 2.保护方法(只有类的内部和该该 ...