[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个左右吧?
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<bitset>
//#include<ctime>
#define ll long long
#define ull unsigned long long
#define ui unsigned int
#define d double
//#define ld long double
using namespace std;
const int maxn=,modd=;const d eps=1e-;
struct zs{int too,pre;}e[maxn<<],E[maxn];int tot,last[maxn],TOT,LAST[maxn];
int sz[maxn];bool leaf[maxn],gg[maxn];
d f[(<<)+];int g[(<<)+];
int i,j,k,n,m; int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<'')rx=getchar();
while(rx>='')ra=ra*+rx-,rx=getchar();return ra;
} void dfs(int x,int fa){
int son=;
for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa)
dfs(e[i].too,x),son++,sz[x]+=sz[e[i].too];
leaf[x]=!son,sz[x]++;
gg[x]=!leaf[x]&&son==;
} inline void insert(int a,int b){
e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
}
inline void ins(int a,int b){
E[++TOT].too=b,E[TOT].pre=LAST[a],LAST[a]=TOT;
}
int a[maxn],cnt;int pos[],LEAF;int sz1[maxn],got[maxn];int num[maxn];
void dfs2(int x,int _fa,int tmp){
if(!gg[x]){
a[++cnt]=x,num[cnt]=tmp;
if(leaf[x])pos[LEAF++]=cnt;
if(_fa)ins(_fa,cnt);
_fa=cnt,tmp=;
}
for(int i=last[x];i;i=e[i].pre)if(sz[e[i].too]<sz[x])dfs2(e[i].too,_fa,tmp+);
}
int main(){
n=read();
for(i=;i<n;i++)insert(read(),read());
dfs(,),dfs2(,,); // for(i=1;i<=cnt;i++)printf(" %d",num[i]);puts("");
// for(i=0;i<LEAF;i++)printf(" %d",pos[i]);puts(""); for(j=;j<LEAF;j++)sz1[pos[j]]=;
for(j=cnt;j;j--)for(k=LAST[j];k;k=E[k].pre)sz1[j]+=sz1[E[k].too]; f[]=g[]=;int mx=<<LEAF,st,tozt,tog;d tof;register int j,k;
for(i=;i<mx-;i++){
memset(got+,,cnt<<);
for(j=;j<LEAF;j++)got[pos[j]]=(i&(<<j))>; for(j=cnt,st=;j;st+=got[j]==sz1[j]?num[j]:,j--)
for(k=LAST[j];k;k=E[k].pre)got[j]+=got[E[k].too];
tof=f[i]*st,tog=1ll*g[i]*st%modd;
// printf("zt:%d st:%d\n",i,st);
for(j=;j<LEAF;j++)if(!(i&(<<j))&& f[tozt=(i|(<<j))]<tof )f[tozt]=tof,g[tozt]=tog;
}printf("%d\n",g[mx-]);
}
[51nod1673]树有几多愁的更多相关文章
- 51nod1673 树有几多愁 - 贪心策略 + 虚树 + 状压dp
传送门 题目大意: 给一颗重新编号,叶子节点的值定义为他到根节点编号的最小值,求所有叶子节点值的乘积的最大值. 题目分析: 为什么我觉得这道题最难的是贪心啊..首先要想到 在一条链上,深度大的编号要小 ...
- 题解 [51nod1673] 树有几多愁
题面 解析 这题思路挺秒啊. 本麻瓜终于找了道好题了(还成功把ztlztl大仙拖下水了) 看到叶子节点数<=20就应该是状压啊. 然而DP要怎么写啊? 首先,考虑到编号肯定是从下往上一次增大的, ...
- 刷题总结——树有几多愁(51nod1673 虚树+状压dp+贪心)
题目: lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输 ...
- 51nod 1673 树有几多愁
lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出最大烦 ...
- 51nod 1673 树有几多愁(链表维护树形DP+状压DP)
题意 lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出 ...
- 51nod 1673 树有几多愁——虚树+状压DP
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1673 建一个虚树. 一种贪心的想法是把较小的值填到叶子上,这样一个小值限制到的 ...
- 51nod算法马拉松13
A 取余最长路 不难发现路径可以拆成三条线段,只要知道两个转折点的位置就能计算出答案. 设sum(i,l,r)表示第i行从l到r元素的和,则答案可以表示为sum(1,1,x)+sum(2,x,y)+s ...
- 20160218.CCPP体系详解(0028天)
程序片段(01):加法.c 内容概要:字符串计算表达式 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <st ...
- 20160218.CCPP体系具体解释(0028天)
程序片段(01):加法.c 内容概要:字符串计算表达式 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <st ...
随机推荐
- 排查程序死循环,死锁的方法 ——pstack
pstack命令可显示每个进程的栈跟踪,pstack $pid即可,pstack命令须由$pid进程的属主或者root运行. 这次出现cpu占比100%的情况,但看memory占比,并无异常,怀疑是某 ...
- JavaWeb之数据源连接池(4)---自定义数据源连接池
[续上文<JavaWeb之数据源连接池(3)---Tomcat>] 我们已经 了解了DBCP,C3P0,以及Tomcat内置的数据源连接池,那么,这些数据源连接池是如何实现的呢?为了究其原 ...
- async和enterproxy控制并发数量
聊聊并发与并行 并发我们经常提及之,不管是web server,app并发无处不在,操作系统中,指一个时间段中几个程序处于已经启动运行到完毕之间,且这几个程序都是在同一处理机上运行,并且任一个时间点只 ...
- DeepLearning.ai学习笔记(三)结构化机器学习项目--week1 机器学习策略
一.为什么是ML策略 如上图示,假如我们在构建一个喵咪分类器,数据集就是上面几个图,训练之后准确率达到90%.虽然看起来挺高的,但是这显然并不具一般性,因为数据集太少了.那么此时可以想到的ML策略有哪 ...
- geoserver发布地图服务WMS
wms服务发布: 1.打开geoserver管理首页(网址为http://localhost:8080/geoserver/web/),并使用安装时设置的帐户名和密码登录(这里是admin/geose ...
- ArcGIS 网络分析[8.1] 资料1 使用AO打开或创建网络数据集之【打开】
为了创建或打开一个网络数据集,你必须使用NetworkDatasetFDExtension对象(文件地理数据库中的数据集)或NetworkDatasetWorkspaceExtension对象(对于S ...
- UVALive 3177 Beijing Guards
题目大意:给定一个环,每个人要得到Needi种物品,相邻的人之间不能得到相同的,问至少需要几种. 首先把n=1特判掉. 然后在n为偶数的时候,答案就是max(Needi+Needi+1)(包括(1,n ...
- Wamp环境搭建常见错误问题解决
第一点.对于apache + php + mysql 的版本的正确选择 问题:网上有些教学视频已经很早了,然后很多人照着来,完全和视频里讲的一样,但是结果就是搭建不成功. 出现问题原因:三件套的版本选 ...
- java之自动过滤提交文本中的html代码script代码
public class test { public static String Html2Text(String inputString) { String htmlStr = inputStrin ...
- gitlab 本地 定时备份
=============================================== 20171015_第1次修改 ccb_warlock === ...