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. Beta Scrum博客集

    听说 Beta Scrum Day 1

  2. C语言的第一次作业

    一.PTA实验作业 题目1. 温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验 ...

  3. 进程与fork()、wait()、exec函数组

    进程与fork().wait().exec函数组 内容简介:本文将引入进程的基本概念:着重学习exec函数组.fork().wait()的用法:最后,我们将基于以上知识编写Linux shell作为练 ...

  4. 个人作业2:QQ音乐APP案例分析

    APP案例分析 QQ音乐 选择理由:毕竟作为QQ音乐九年的资深老用户以及音乐爱好者 第一部分 调研 1.第一次上手的体验    我算是很早期的QQ音乐的用户,用QQ音乐七八年,除了体验各方面还不错之外 ...

  5. 冲刺NO.5

    Alpha冲刺第五天 站立式会议 项目进展 今日项目完成内容主要包括了JS的学习,事务管理员模块与学生模块的完善与补充,并且开始编写信用信息管理模块和奖惩事务管理模块. 问题困难 前端部分的技术掌握的 ...

  6. fflush(stdin)与fflush(stdout)

    1.fflush(stdin): 作用:清理标准输入流,把多余的未被保存的数据丢掉.. 如: int main() { int num; char str[10]; cin>>num; c ...

  7. scrapy 避免被ban

    1.settings.pyCOOKIES_ENABLED = False DOWNLOAD_DELAY = 3 ROBOTSTXT_OBEY = Falseip代理池设置 IPPOOL = [{'ip ...

  8. android context获取目录详解

    获取 sqlite系统数据库路径 方式1: ApkInfo apkInfo = new ResourceUtil(context).getApkInfo(); APP_PATH = new Strin ...

  9. OpenCASCADE Trihedron Law

    OpenCASCADE Trihedron Law eryar@163.com Abstract. In differential geometry the Frenet-Serret formula ...

  10. CentOS7 防火墙firewalld详细操作

    1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld  停止: systemctl disab ...