4天终于做出来了,没错我就是这么蒟蒻。教训还是很多的。

  建议大家以后编树形DP不要用记忆化搜索,回溯转移状态个人感觉更有条理性。

  大神题解传送门 by iwtwiioi

  我的题解大家可以看注释"//"部分

  本题我用的树形DP中dp[x][fa][need]表示编号为x的节点的父亲选(1)没选(0),x的父亲需(1)不需要(0)其他节点来覆盖。

若父亲节点选了,则need肯定为0,所以不存在fa==1而need==1的状态,相当于浪费了¼的空间。毕竟数据范围比较小,而且程序要有可读性!程序要有可读性!程序要有可读性!我这么写代码不是加强了程序的可读性吗?像iwtwiioi那样用012表示状态题解和程序的可读性大大降低,大家在读题解时难免要费点劲。并没有贬义!!!╮(╯_╰)╭

my code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int point[],next[],v[],cnt=,N,l[],r[],pre[],con[];
const long long mo=;
long long f[][][];
int dp[][][];
bool p[];
void memsetf(){for(int i=;i<=N;++i)for(int j=;j<;++j)for (int k=;k<;++k)f[i][j][k]=;}
void insect(int x,int y){next[cnt]=point[x];point[x]=cnt;v[cnt]=y;cnt++;}
void dfs(int x)
{
if (x==) return;
int i,j=;
for (i=point[x];i!=-;i=next[i])
if (p[v[i]]==)
{
p[v[i]]=;
if (l[x]==) {l[x]=v[i];j=v[i];}
else {r[j]=v[i];pre[v[i]]=j;j=v[i];}
}
dfs(j); con[j]=con[l[j]]+;
while (pre[j]!=-){j=pre[j]; dfs(j); con[j]=con[l[j]]+con[r[j]]+;}
}
void work(int x)
{
if (r[x]!=) work(r[x]);
if (l[x]!=) work(l[x]);
long long s=; int num=;
if ((l[x]==)&&(r[x]==))
{
dp[x][][]=; dp[x][][]=; dp[x][][]=; return;
}
else
if (l[x]==)
{
dp[x][][]=+dp[r[x]][][]; f[x][][]=f[r[x]][][];
dp[x][][]=+dp[r[x]][][]; f[x][][]=f[r[x]][][];
dp[x][][]=dp[r[x]][][]; f[x][][]=f[r[x]][][];
return;
}
else
if (r[x]==)
{
dp[x][][]=+dp[l[x]][][]; f[x][][]=f[l[x]][][];
//dp[x][0][0]=min(1+dp[l[x]][1][0],dp[l[x]][0][1]);
if (+dp[l[x]][][]<dp[l[x]][][])
dp[x][][]=+dp[l[x]][][],f[x][][]=f[l[x]][][];
else
if (+dp[l[x]][][]>dp[l[x]][][])
dp[x][][]=dp[l[x]][][],f[x][][]=f[l[x]][][];
else
dp[x][][]=dp[l[x]][][],f[x][][]=(f[l[x]][][]+f[l[x]][][])%mo;
//dp[x][1][0]=min(1+dp[l[x]][1][0],dp[l[x]][0][0]);
if (+dp[l[x]][][]<dp[l[x]][][])
dp[x][][]=+dp[l[x]][][],f[x][][]=f[l[x]][][];
else
if (+dp[l[x]][][]>dp[l[x]][][])
dp[x][][]=dp[l[x]][][],f[x][][]=f[l[x]][][];
else
dp[x][][]=dp[l[x]][][],f[x][][]=(f[l[x]][][]+f[l[x]][][])%mo;
return;
}
//dp[x][0][1]=min(dp[x][0][1],dp[l[x]][0][1]+dp[r[x]][0][1]);
//dp[x][0][1]=min(dp[x][0][1],1+dp[l[x]][1][0]+dp[r[x]][0][0]);
if (dp[l[x]][][]+dp[r[x]][][]<+dp[l[x]][][]+dp[r[x]][][])
dp[x][][]=dp[l[x]][][]+dp[r[x]][][],f[x][][]=(f[l[x]][][]*f[r[x]][][])%mo;
else
if (dp[l[x]][][]+dp[r[x]][][]>+dp[l[x]][][]+dp[r[x]][][])
dp[x][][]=+dp[l[x]][][]+dp[r[x]][][],f[x][][]=(f[l[x]][][]*f[r[x]][][])%mo;
else
{
dp[x][][]=+dp[l[x]][][]+dp[r[x]][][];
f[x][][]=((f[l[x]][][]*f[r[x]][][])%mo+(f[l[x]][][]*f[r[x]][][])%mo)%mo;
}
//dp[x][0][0]=min(dp[x][0][0],dp[l[x]][0][1]+dp[r[x]][0][0]);
//dp[x][0][0]=min(dp[x][0][0],1+dp[l[x]][1][0]+dp[r[x]][0][0]);
if (dp[l[x]][][]+dp[r[x]][][]<+dp[l[x]][][]+dp[r[x]][][])
dp[x][][]=dp[l[x]][][]+dp[r[x]][][],f[x][][]=(f[l[x]][][]*f[r[x]][][])%mo;
else
if (dp[l[x]][][]+dp[r[x]][][]>+dp[l[x]][][]+dp[r[x]][][])
dp[x][][]=+dp[l[x]][][]+dp[r[x]][][],f[x][][]=(f[l[x]][][]*f[r[x]][][])%mo;
else
{
dp[x][][]=+dp[l[x]][][]+dp[r[x]][][];
f[x][][]=((f[l[x]][][]*f[r[x]][][])%mo+(f[l[x]][][]*f[r[x]][][])%mo)%mo;
}
//dp[x][1][0]=min(dp[x][1][0],dp[l[x]][0][0]+dp[r[x]][1][0]);
//dp[x][1][0]=min(dp[x][1][0],1+dp[l[x]][1][0]+dp[r[x]][1][0]);
if (dp[l[x]][][]+dp[r[x]][][]<+dp[l[x]][][]+dp[r[x]][][])
dp[x][][]=dp[l[x]][][]+dp[r[x]][][],f[x][][]=(f[l[x]][][]*(f[r[x]][][]))%mo;
else
if (dp[l[x]][][]+dp[r[x]][][]>+dp[l[x]][][]+dp[r[x]][][])
dp[x][][]=+dp[l[x]][][]+dp[r[x]][][],f[x][][]=(f[l[x]][][]*f[r[x]][][])%mo;
else
{
dp[x][][]=+dp[l[x]][][]+dp[r[x]][][];
f[x][][]=((f[l[x]][][]*(f[r[x]][][]))%mo+(f[l[x]][][]*f[r[x]][][])%mo)%mo;
}
}
int main()
{
memset(point,-,sizeof(point));
memset(next,-,sizeof(next));
memset(pre,-,sizeof(pre));
memset(dp,,sizeof(dp));
memset(v,,sizeof(v));
memset(p,,sizeof(p));
memset(l,,sizeof(l));
memset(r,,sizeof(r));
scanf("%d\n",&N);
memsetf();
int i,x,y;
for (i=;i<N;++i)
{
scanf("%d %d\n",&x,&y);
insect(x,y);insect(y,x);
}p[]=;dfs();
work(l[]);
if (dp[l[]][][]<(+dp[l[]][][]))
printf("%d\n%I64d\n",dp[l[]][][],f[l[]][][]);
else
if (dp[l[]][][]>(+dp[l[]][][]))
printf("%d\n%I64d\n",+dp[l[]][][],f[l[]][][]);
else
printf("%d\n%I64d\n",+dp[l[]][][],(f[l[]][][]+f[l[]][][])%mo);
return ;
}
P1770大内密探

 
 

背景

大内密探,负责秘密保护皇上,还有保护皇宫内外一切产业。——大内密探零零七

描述

在古老的皇宫中,有N个房间以及N-1条双向通道,每条通道连接着两个不同的房间,所有的房间都能互相到达。皇宫中有许多的宝物,所以需要若干个大内密探来守护。一个房间被守护当切仅当该房间内有一名大内密探或者与该房间直接相邻的房间内有大内密探。

现在身为大内密探零零七的你想知道要把整个皇宫守护好至少需要多少名大内密探以及有多少种安排密探的方案。两种方案不同当且仅当某个房间在一种方案有密探而在另一个方案内没有密探。

格式

输入格式

第一行一个正整数N.(1<=N<=100000)
后面N-1行,每行两个正整数a和b,表示房间a和房间b之间有一条无向通道。

房间的编号从1到N

输出格式

第一行输出正整数K,表示最少安排的大内密探。

第二行输出整数S,表示有多少种方案安排最少的密探,由于结果可能较大,请输出方案数mod 1000000007的余数。

样例1

样例输入1[复制]

 
7
2 1
3 1
4 2
5 1
6 2
7 6

样例输出1[复制]

 
3
4

限制

每个测试点1s

提示

30%保证:n <= 10
70%保证:n <= 1000
100%保证:n <= 100000

Vijos p1770 大内密探 树形DP+计数的更多相关文章

  1. Vijos p1518河流 树形DP

    https://vijos.org/p/1518 这题代码我基本是抄的,实在太难想了.但是也学到了一些东西. 比如:多叉树转二叉树存,这个细细一想,确实使得在dfs的时候,实现起来方便很多. 说一说具 ...

  2. vijos 1180 选课 树形DP

    描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核通过就能获得 ...

  3. Codeforces Round #277 (Div. 2)D(树形DP计数类)

    D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  4. 【vijos】1770 大内密探(树形dp+计数)

    https://vijos.org/p/1770 不重不漏地设计状态才能正确的计数QAQ 虽然可能最优化是正确的,但是不能保证状态不相交就是作死.... 之前设的状态错了... 应该设 f[i][0] ...

  5. Vijos p1892 树上的最大匹配 树形DP+计数 被卡常我有特殊技巧heheda

    https://vijos.org/p/1892 此题需要手动开栈: <<; //256MB char *p=(char*)malloc(size)+size; __asm__(" ...

  6. 【vijos】1892 树上的最大匹配(树形dp+计数)

    https://vijos.org/p/1892 这个必须得卡评测机+手动开栈才能卡过QAQ 手动开栈我百度的... int size=256<<20; //256MB char *p=( ...

  7. Tree Cutting (Hard Version) CodeForces - 1118F2 (树形DP,计数)

    大意:给定树, 每个点有颜色, 一个合法的边集要满足删除这些边后, 每个连通块内颜色仅有一种, 求所有合法边集的个数 $f[x][0/1]$表示子树$x$中是否还有与$x$连通的颜色 对于每种颜色已经 ...

  8. 牛客第八场 C-counting paths 树形dp计数

    题目地址 题意 给你一颗树 初始点颜色全部为白色 对于每一个满足要求一的点集s f(s)的定义为先把点集内的点染黑 满足要求二的路径集合数量 要求一为两两黑点之间不能出现白色的点 要求二为将这个路径集 ...

  9. 『树上匹配 树形dp』

    树上匹配 Description 懒惰的温温今天上班也在偷懒.盯着窗外发呆的温温发现,透过窗户正巧能看到一棵 n 个节点的树.一棵 n 个节点的树包含 n-1 条边,且 n 个节点是联通的.树上两点之 ...

随机推荐

  1. C之五子棋

    #include <stdio.h> #include <stdlib.h> #define N 15 ][N + ] = { }; ; void initGame(void) ...

  2. 【jQuery Demo】jQuery打造动态下滑菜单

    作者:漫凯维奇      来源:[教程]jQuery打造动态下滑菜单 Tip:这只是一个转载,源代码可以在上面的来源博文中下载 此教程将分步讲解如何使用JQuery和CSS打造一个炫酷动感菜单.效果如 ...

  3. activiti自定义流程之整合(三):整合自定义表单创建模型

    本来在创建了表单之后应该是表单列表和预览功能,但是我看了看整合的代码,和之前没有用angularjs的基本没有什么变化,一些极小的变动也只是基于angularjs的语法,因此完全可以参考之前说些的表单 ...

  4. HTML5本地存储localStorage与sessionStorage

    在最近的项目中用到了html5的本地存储,下面总结一下. 1.html5几种存储形式 本地存储(localStorage && sessionStorage) 离线缓存(applica ...

  5. Android Studio运行程序出现Session ‘app’: Error Launching activity 解决办法

    session "app":error launching activity 一下两种方法,可以轻松解决: 1. 2.把复选框去除:  

  6. Android中的三种XML解析方式

    在Android中提供了三种解析XML的方式:SAX(Simple API XML),DOM(Document Objrect Model),以及Android推荐的Pull解析方式.下面就对三种解析 ...

  7. java 20 - 6 加入了异常处理的字节输出流的操作

    昨天坐了十几个钟的车回家,累弊了.... ————————————割掉疲劳————————————— 前面的字节输出流都是抛出了异常不管,这次的加入了异常处理: 首先还是创建一个字节输出流对象,先给它 ...

  8. XCode的 Stack Trace,调试时抛出异常,定位到某一行代码

    在Xcode调试程序的时候,总是会出现不知道错误在什么地方的问题,很是捉急,现在又一个办法,可以具体定位到错误行的代码,试一下吧?超级好用 操作很简单: 1.在XCode界面中按cmd + 6快捷键, ...

  9. http请求过程

    想象用浏览器打开imooc.com网站,HTTP走过的环节: 1.首先,是对imooc.com域名解析,(1.1)浏览器搜索浏览器自身的DNS缓存.(DNS(Domain Name System,域名 ...

  10. DRDB报错------0: Failure: (119) No valid meta-data signature found.

    一. 错误 drbdadm create-md datadrbdadm up data  <--启动时报错 [root@data-- ~]# drbdadm up data : Failure: ...