题目描述

外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY 已经联系好了黄金舰队,打算联合所有 JSOIer 抵御外星人的进攻。

在黄金舰队就位之前,JYY 打算事先了解外星人的进攻计划。现在,携带了监听设备的特工已经秘密潜入了外星人的母舰,准备对外星人的通信实施监听。

外星人的母舰可以看成是一棵 n 个节点、 n-1 条边的无向树,树上的节点用 1,2,\cdots,n1,2,⋯,n 编号。JYY 的特工已经装备了隐形模块,可以在外星人母舰中不受限制地活动,可以神不知鬼不觉地在节点上安装监听设备。

如果在节点 uu 上安装监听设备,则 JYY 能够监听与 uu 直接相邻所有的节点的通信。换言之,如果在节点 uu 安装监听设备,则对于树中每一条边 (u,v),节点 vv 都会被监听。特别注意放置在节点 uu 的监听设备并不监听 uu 本身的通信,这是 JYY 特别为了防止外星人察觉部署的战术。

JYY 的特工一共携带了 kk个监听设备,现在 JYY 想知道,有多少种不同的放置监听设备的方法,能够使得母舰上所有节点的通信都被监听?为了避免浪费,每个节点至多只能安装一个监听设备,且监听设备必须被用完。

输入格式

输入第一行包含两个整数 n,kn,k ,表示母舰节点的数量 nn 和监听设备的数量 kk 。 接下来 n-1n−1 行,每行两个整数 u,vu,v (1\le u,v\le n)(1≤u,v≤n),表示树中的一条边。

输出格式

输出一行,表示满足条件的方案数。因为答案可能很大,你只需要输出答案 \(\text{mod 1,000,000,007}\)的余数即可。

显然是树形DP

但是推状态转移方程很想死啊!

\(首先说一下DP[i][j][0/1][0/1]表示在树上的i点,一共放了j个监听设备,点i是否被覆盖,点i上是否有监听设备时,监听覆盖完点i的子树(不包括i)有多少种方案\)。

\(显然我们在dfs中更新时,是从儿子更新父亲,所以上面指的覆盖是指儿子对父亲的覆盖。还有我们需要设另一个数组来DP,设那个数组为dp1\)

接下来就是恶心的四种情况讨论了。

首先,如果这个点更新后是DP[u][j][0][0]。

因为u没有被覆盖,所以son上一定没有监听设备,又因为需要完全覆盖,u不可能对son进行覆盖,所以son一定要被覆盖。

dp[u][i+j][0][0]=(dp[u][i+j][0][0]+(dp1[i][0][0]*1ll*dp[v][j][1][0])%mod)%mod;

如果是DP[u][j][0][1]。

因为u没有被覆盖,所以son上一定没有监听设备,又因为u上有监听设备,所以son有没有被覆盖都行。

dp[u][i+j][0][1]=(dp[u][i+j][0][1]+(dp1[i][0][1]*1ll*(dp[v][j][1][0]+dp[v][j][0][0])%mod)%mod)%mod;

如果是DP[u][j][1][0]。

因为u被覆盖了,所以u的更新之前的状态有可能没有被覆盖,或者被覆盖了,所以dp可以由两种更新前的状态(0,0)或(1,0)更新。

1.由(0,0)更新过来

这样的话,因为最终状态要求被覆盖,所以son上必须要有监听设备,又因为u不能对son进行覆盖,所以son一定要被覆盖。

2.由(1,0)更新过来

同理,因为u之前已经被覆盖了,所以son上有没有监听设备都可以,又因为u不能对son进行覆盖,所以son一定要被覆盖。

dp[u][i+j][1][0]=(dp[u][i+j][1][0]+((dp1[i][0][0]*1ll*dp[v][j][1][1])%mod+0ll+(dp1[i][1][0]*1ll*(dp[v][j][1][0]+dp[v][j][1][1])%mod)%mod)%mod)%mod;

如果是DP[u][j][1][1]。

像上种情况一样,这种的dp也可以又两种更新前的状态(0,1)或(1,1)

1.由(0,1)更新过来

因为u上有监听设备,所以son上有没有被覆盖都可以,又因为u没有被覆盖(状态上要求被覆盖),所以son上有监听设备。

2.由(1,1)更新过来

同理,不过这次u已经被覆盖了,所以son上有没有监听设备都可以。

dp[u][i+j][1][1]=(dp[u][i+j][1][1]+(dp1[i][0][1]*1ll*(dp[v][j][1][1]+dp[v][j][0][1])%mod)%mod+0ll+(dp1[i][1][1]*1ll*((((dp[v][j][1][0]+dp[v][j][1][1])%mod+dp[v][j][0][0])%mod+dp[v][j][0][1])%mod)%mod)%mod)%mod;

综上,四种情况的分类讨论已经完毕,程序主体也写出来了。

两个初始化:

dp[u][0][0][0]=dp[u][1][0][1]=1;
#include<bits/stdc++.h>
#define mod 1000000007
#define N 100010
#define M 110
using namespace std;
int n,m,to[N<<1],nxt[N<<1],head[N],cnt,size[N],x,y,dp[N][M][2][2],dp1[M][2][2];//哪一个点,子树放了几个,u是否覆盖,u是否放
void adde(int x,int y)
{
to[++cnt]=y;
nxt[cnt]=head[x];
head[x]=cnt;
}
void dfs(int u,int fa)
{
size[u]=1;
dp[u][0][0][0]=dp[u][1][0][1]=1;
for(int k=head[u];k;k=nxt[k])
{
int v=to[k];
if(v!=fa)
{
dfs(v,u);
for(int i=0;i<=m;i++)
{
dp1[i][0][0]=dp[u][i][0][0];
dp[u][i][0][0]=0;
dp1[i][1][0]=dp[u][i][1][0];
dp[u][i][1][0]=0;
dp1[i][0][1]=dp[u][i][0][1];
dp[u][i][0][1]=0;
dp1[i][1][1]=dp[u][i][1][1];
dp[u][i][1][1]=0;
}
for(int i=0;i<=min(size[u],m);i++)
{
for(int j=0;j<=min(size[v],m-i);j++)
{
dp[u][i+j][0][0]=(dp[u][i+j][0][0]+(dp1[i][0][0]*1ll*dp[v][j][1][0])%mod)%mod;
dp[u][i+j][0][1]=(dp[u][i+j][0][1]+(dp1[i][0][1]*1ll*(dp[v][j][1][0]+dp[v][j][0][0])%mod)%mod)%mod;
dp[u][i+j][1][0]=(dp[u][i+j][1][0]+((dp1[i][0][0]*1ll*dp[v][j][1][1])%mod+0ll+(dp1[i][1][0]*1ll*(dp[v][j][1][0]+dp[v][j][1][1])%mod)%mod)%mod)%mod;
dp[u][i+j][1][1]=(dp[u][i+j][1][1]+(dp1[i][0][1]*1ll*(dp[v][j][1][1]+dp[v][j][0][1])%mod)%mod+0ll+(dp1[i][1][1]*1ll*((((dp[v][j][1][0]+dp[v][j][1][1])%mod+dp[v][j][0][0])%mod+dp[v][j][0][1])%mod)%mod)%mod)%mod;
}
}
size[u]+=size[v];
}
}
}
int main()
{
// freopen("1.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
adde(x,y);
adde(y,x);
}
dfs(1,-1);
printf("%d\n",(dp[1][m][1][0]+dp[1][m][1][1])%mod);
return 0;
}

附:好像DP开long long就会爆空间,所以好好写mod吧!!!

[loj2546][JSOI2018]潜入行动(树形DP)的更多相关文章

  1. BZOJ5314: [Jsoi2018]潜入行动 (树形DP)

    题意:一棵树选择恰好k个结点放置监听器 每个监听器只能监听相邻的节点 问能使得所有节点被监听的种类数 题解:反正就是很well-known的树形DP了 至于时间复杂度为什么是nk 不会不学 很好想到四 ...

  2. LOJ 2546 「JSOI2018」潜入行动——树形DP

    题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...

  3. [JSOI2018]潜入行动 (树形背包)

    题目链接 题意: 外星人的母舰可以看成是一棵 n 个节点. n−1 条边的无向树,树上的节点用 1,2,⋯,n 编号.JYY 的特工已经装备了隐形模块,可以在外星人母舰中不受限制地活动,可以神不知鬼不 ...

  4. [JSOI2018]潜入行动 树形DP_复杂计数

    code #include <cstdio> #include <algorithm> #include <cstring> #include <string ...

  5. 【BZOJ5314】[JSOI2018]潜入行动(动态规划)

    [BZOJ5314][JSOI2018]潜入行动(动态规划) 题面 BZOJ 洛谷 题解 不难想到一个沙雕\(dp\),设\(f[i][j][0/1][0/1]\)表示当前点\(i\),子树中一共放了 ...

  6. BZOJ5314:[JSOI2018]潜入行动——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5314 https://www.luogu.org/problemnew/show/P4516 ht ...

  7. [BZOJ4824][CQOI2017]老C的键盘(树形DP)

    4824: [Cqoi2017]老C的键盘 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 193  Solved: 149[Submit][Statu ...

  8. BZOJ5314: [Jsoi2018]潜入行动

    BZOJ5314: [Jsoi2018]潜入行动 https://lydsy.com/JudgeOnline/problem.php?id=5314 分析: 裸树形背包,设\(f[x][i][0/1] ...

  9. luogu P4516 [JSOI2018]潜入行动

    LINK:潜入行动 初看题感觉很不可做 但是树形dp的状态过于明显. 容易设\(f_{x,j,l,r}\)表示x为根子树内放了j个设备且子树内都被覆盖l表示x是否被覆盖r表示x是否放设备的方案数. 初 ...

随机推荐

  1. 如何评价一个VR体验设计?

    如何评价一个VR系统的体验是好是坏?或者说,哪些因素会破坏一个VR的体验? Kruij和Riecke教授在IEEE VR会议上提到了四个角度:Congnition,Game User Experien ...

  2. .Net Core与Vue.js模块化前后端分离快速开发解决方案(NetModular)

    NetModular是什么? NetModular不仅仅是一个框架,它也是一整套的模块化与前后端分离的快速开发的解决方案,目标是致力于开箱即用,让开发人员完全专注于业务开发,不需要关心底层封装和实现. ...

  3. [Note] CentOS 命令

    1. uninstall software install by yum install yum install -y [package-name] //无-y则交互式安装 yum remove [p ...

  4. 设计模式----行为型模式之命令模式(Command Pattern)

    下面来自head first设计模式的命令模式一章节. 定义 将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 类图 注: 1. ...

  5. Feign【文件上传】

    话不多说,上代码.... 项目公共依赖配置: <parent> <groupId>org.springframework.boot</groupId> <ar ...

  6. Java技能树-图片版

    最近在总结技能树,打算先拓宽下视野和技术的广度,后面会详细研究每个常用的技术点,补充技术的深度!下面是我在ProcessOn上总结的,里面有些有注释,点击这里注册ProcessOn,点击这里,可查看或 ...

  7. Liang-Barsky算法

    Liang-Barsky算法 在Cohen-Sutherland算法提出后,梁友栋和Barsky又针对标准矩形窗口提出了更快的Liang-Barsky直线段裁剪算法. 梁算法的主要思想: (1)用参数 ...

  8. 机器学习回顾篇(7):决策树算法(ID3、C4.5)

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  9. Linux低权限用户记录ssh密码

    0x01 场景 现在有个攻击场景,就是你拿到了linux外网服务器的webshell,要做内网渗透前肯定要收集信息.其中可以做的一个工作是重新编译ssh来记录管理员的密码信息,信息可以用来撞其他机器的 ...

  10. [BZOJ29957] 楼房重建 - 线段树

    2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3294  Solved: 1554[Submit][Status][Discus ...