TYOI Day1 travel:Tree dp【处理重复走边】
题意:
给你一棵树,n个节点,每条边有长度。
然后有q组询问(u,k),每次问你:从节点u出发,走到某个节点的距离mod k的最大值。
题解:
对于无根树上的dp,一般都是先转成以1为根的有根树,然后分别从上到下和从下到上两遍dp。
另一个技巧是:处理重复走边的情况时,可以让dp值表示达到某种状态的方案数。
表示状态:
dp[i][j][k] = max dis
表示从i节点出发,走的距离mod k = j时的方案数
找出答案:
对于每次询问(u,k),答案为:满足dp[u][d][k]>0的最大的d值。
如何转移:
第一遍dfs:
dp[i][(j+len)%k][k] = ∑ dp[son][j][k]
只考虑从上往下的路径。
第二遍dfs:
dp[i][(j+len)%k][k] += dp[par][j][k]
dp[i][(j+len)%k][k] -= old[i][((j-len)%k+k)%k][k]
其中old[i][j][k]代表原来的dp,即只考虑从上往下时的dp。
减去old是因为要将会导致重复走边的方案删去。
边界条件:
dp[i][0][k] = 1
others = 0
复杂度:
Tree dp: O(n*k*k)
Query: O(q*k)
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 3005
#define MAX_K 105 using namespace std; struct Edge
{
int dst;
int len;
Edge(int _dst,int _len)
{
dst=_dst;
len=_len;
}
Edge(){}
}; int n,q;
int dp[MAX_N][MAX_K][MAX_K];
int old[MAX_N][MAX_K][MAX_K];
vector<Edge> edge[MAX_N]; void read()
{
cin>>n;
int x,y,z;
for(int i=;i<n;i++)
{
cin>>x>>y>>z;
edge[x].push_back(Edge(y,z));
edge[y].push_back(Edge(x,z));
}
} void dfs1(int now,int p)
{
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dst!=p) dfs1(temp.dst,now);
}
for(int k=;k<=;k++)
{
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dst!=p)
{
for(int j=;j<k;j++)
{
dp[now][(j+temp.len)%k][k]+=dp[temp.dst][j][k];
}
}
}
}
} void dfs2(int now,int p,int l)
{
if(p!=-)
{
for(int k=;k<=;k++)
{
for(int j=;j<k;j++)
{
old[now][j][k]=dp[now][j][k];
}
}
for(int k=;k<=;k++)
{
for(int j=;j<k;j++)
{
dp[now][(j+l)%k][k]+=dp[p][j][k];
dp[now][(j+l)%k][k]-=old[now][((j-l)%k+k)%k][k];
}
}
}
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dst!=p) dfs2(temp.dst,now,temp.len);
}
} void work()
{
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++)
{
for(int k=;k<=;k++)
{
dp[i][][k]=;
}
}
dfs1(,-);
dfs2(,-,);
cin>>q;
int u,k;
while(q--)
{
cin>>u>>k;
for(int d=k-;d>=;d--)
{
if(dp[u][d][k])
{
cout<<d<<endl;
break;
}
}
}
} int main()
{
read();
work();
}
TYOI Day1 travel:Tree dp【处理重复走边】的更多相关文章
- 96. Unique Binary Search Trees (Tree; DP)
Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...
- HDU 4359——Easy Tree DP?——————【dp+组合计数】
Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- HDU 4359 Easy Tree DP?
Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- poj 3230 Travel(dp)
Description One traveler travels among cities. He has to pay for this while he can get some incomes. ...
- Codeforces 442D Adam and Tree dp (看题解)
Adam and Tree 感觉非常巧妙的一题.. 如果对于一个已经建立完成的树, 那么我们可以用dp[ i ]表示染完 i 这棵子树, 并给从fa[ i ] -> i的条边也染色的最少颜色数. ...
- HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)
Tree chain problem Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- HDU3534(SummerTrainingDay13-C tree dp)
Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- BZOJ.1576.[Usaco2009 Jan]安全路经Travel(树形DP 并查集)
题目链接 BZOJ 洛谷 先求最短路树.考虑每一条非树边(u,v,len),设w=LCA(u,v),这条边会对w->v上的点x(x!=w)有dis[u]+dis[v]-dis[x]+len的距离 ...
- Partial Tree(DP)
Partial Tree http://acm.hdu.edu.cn/showproblem.php?pid=5534 Time Limit: / MS (Java/Others) Memory Li ...
随机推荐
- FPGA开发流程
需求说明:Verilog设计 内容 :FPGA开发基本流程及注意事项 来自 :时间的诗 原文来自:http://www.dzsc.com/data/2015-3-16/1080 ...
- PHP性能之语言性能优化:vld——查看代码opcode的神器
vld介绍 vld是PECL(PHP 扩展和应用仓库)的一个PHP扩展,现在最新版本是 0.14.0(2016-12-18),它的作用是:显示转储PHP脚本(opcode)的内部表示(来自PECL的v ...
- 几种session存储方式比较
原文: http://blog.sina.com.cn/s/blog_495697e6010143tj.html 集群中session安全和同步是个最大的问题,下面是我收集到的几种session同步的 ...
- Lumen开发:phpunit单元测试
先来直接运行,cmd先进入根目录,然后进入tests或是test文件夹 运行命令行:..\vendor\bin\phpunit ExampleTest.php laravel/lumen中集成了PHP ...
- Linux环境下,使用PHP创建一个守护进程
<?php $pid = pcntl_fork(); // fork if ($pid < 0) exit; else if ($pid) // parent exit; else { / ...
- Nodejs通过thrift访问Java服务
上一篇文章中实现了用Java作为thrift客户端和服务端.接下来我们用nodejs作为客户端访问一下.Nodejs的安装可以查看http://www.cnblogs.com/xucheng/p/39 ...
- 二、Android应用的界面编程(一)界面编程与视图(View)组件
Android应用的绝大部分UI组件都放在android.widget包及其子包.android.view包及其子包中,Android应用的所有UI组件都继承了View类.它代表一个空白的矩形区域.V ...
- 爬虫入门【2】Requests库简介
发送请求 使用Requests发送网络请求很简单 #首先要导入requests库 import requests #返回一个Response对象 r=requests.get('https://git ...
- 记录-JQuery日历插件My97DatePicker日期范围限制
对于日期控件,有时会有不能选择今天以前的日期这种需求..... My97DatePicker是一个非常优秀的日历插件,不仅支持多种调用模式,还支持日期范围限制. 常规的调用比较简单,如下所示: 1 & ...
- Spring @Configuration注解
1 该注解的用途 这个注解表示这个类可以作为spring ioc容器bean的来源,其本质上它是对xml文件中创建bean的一种替换.有了这个注释,Spring framework就能在需要的时候构造 ...