【BZOJ1063】【NOI2008】道路设计(动态规划)

题面

BZOJ

题解

发现每个点最多只能被修一次等价于每个点最多只能和两条铁路相邻

考虑一个\(dp\)

设\(f[i][0/1/2]\)表示以\(i\)为根,当前点与他的儿子已经有\(0/1/2\)条铁路相邻的方案数

转移也很简单,考虑每个儿子,枚举是修还是不修就行了

这样的复杂度是\(O(n)\)

这样的前提是不需要计算答案的方案数,我们可以很容易想出来

现在考虑如何计算方案数。

考虑一下答案的范围,如果我们把这棵树进行树链剖分

重链视为修铁路,那么任意一个点跳轻边的次数不会超过\(log\)次

所以,答案一定不会超过\(log\)

这样子在做的时候把答案限制也加上就好了

设\(f[i][j][k]\)表示以\(i\)为根的子树,答案为\(j\),

当前点与\(k\)条铁路相邻的方案数,其中\(k\in\{0,1,2\}\)

转移和前面没有太多的区别,只需要注意一下答案那一位的变化就行了

时间复杂度\(O(nlogn)\)

注意一下这道题目要怎么取模

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 100100
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int n,m,MOD;
int f[MAX][20][3];
void add(int &x,int y){x+=y;if(x>MOD)x-=MOD;}
int mod(ll x){if(x!=0&&x%MOD==0)return MOD;return x%MOD;}
void dfs(int u,int ff)
{
for(int i=0;i<20;++i)f[u][i][0]=1;--n;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;
dfs(v,u);
for(int ans=0;ans<19;++ans)
{
int f0=0,f1=0;
if(ans)f0=mod(1ll*f[v][ans-1][0]+f[v][ans-1][1]+f[v][ans-1][2]);
f1=mod(1ll*f[v][ans][0]+f[v][ans][1]);
f[u][ans][2]=mod(1ll*f[u][ans][2]*f0+1ll*f[u][ans][1]*f1);
f[u][ans][1]=mod(1ll*f[u][ans][1]*f0+1ll*f[u][ans][0]*f1);
f[u][ans][0]=mod(1ll*f[u][ans][0]*f0);
}
}
}
int main()
{
n=read();m=read();MOD=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs(1,0);
if(n){puts("-1");puts("-1");return 0;}
int ans=1e9,tot=0;
for(int i=0;i<20;++i)
if(f[1][i][0]||f[1][i][1]||f[1][i][2]){ans=i;break;}
tot=mod(1ll*f[1][ans][0]+f[1][ans][1]+f[1][ans][2])%MOD;
printf("%d\n%d\n",ans,tot);
return 0;
}

最新文章

  1. mac环境brew安装freetype,imagick等yii2所需要的库
  2. NeHe OpenGL教程 第八课:混合
  3. unigui unidbgrid显示列的合计值
  4. 从前有个聊天室(socket&amp;threading)
  5. VC6集成开发环境使用参考
  6. ES 06 - 通过Kibana插件增删改查ES中的索引文档
  7. VS2013 中 CString类型转换为LPCSTR类型
  8. oracle权限列表
  9. 对Python选修课的期望
  10. SpringMVC异步文件上传下载
  11. 运行Maven项目时出现invalid LOC header (bad signature)错误,Tomcat不能正常启动
  12. [转] mongodb下载、安装、配置与使用
  13. Prism中命令可用性无法自动刷新
  14. How can I get the baseurl of site?
  15. 【题解】Luogu P4450 双亲数
  16. Spring &lt;import&gt;标签配置
  17. android camera 摄像头预览画面变形
  18. 微信小程序 - 自定义switch切换(示例)
  19. 解题:APIO 2012 派遣
  20. LR字符串处理

热门文章

  1. 人脸检测及识别python实现系列(3)——为模型训练准备人脸数据
  2. Lua学习笔记(3):运算符
  3. HackRF One硬件架构及参数简介
  4. 阿里巴巴将在美国推出电子商务网站11 Main
  5. Centos上搭建git服务
  6. Heavy Cargo POJ 2263 (Floyd传递闭包)
  7. AVL树 算法思想与代码实现
  8. 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和
  9. Alpha事后诸葛(团队)
  10. css声明的优先级