题意:

  给你一棵树,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【处理重复走边】的更多相关文章

  1. 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 ...

  2. HDU 4359——Easy Tree DP?——————【dp+组合计数】

    Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  3. HDU 4359 Easy Tree DP?

    Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  4. poj 3230 Travel(dp)

    Description One traveler travels among cities. He has to pay for this while he can get some incomes. ...

  5. Codeforces 442D Adam and Tree dp (看题解)

    Adam and Tree 感觉非常巧妙的一题.. 如果对于一个已经建立完成的树, 那么我们可以用dp[ i ]表示染完 i 这棵子树, 并给从fa[ i ] -> i的条边也染色的最少颜色数. ...

  6. HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  7. HDU3534(SummerTrainingDay13-C tree dp)

    Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. 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的距离 ...

  9. Partial Tree(DP)

    Partial Tree http://acm.hdu.edu.cn/showproblem.php?pid=5534 Time Limit: / MS (Java/Others) Memory Li ...

随机推荐

  1. 一家O2O社区App公司的随笔

    近两年,O20是业内最火爆的关键词之一,去年拿到1亿天使投资的叮咚小区都引起了各方的关注. 一个月之前我入职了一家以做O2O社区产品的创业公司,此文会把这段时间和后边所见所想都写出来,总结创业公司和创 ...

  2. iOS ZipArchive文件解压缩

    ZipArchive可以用于iOS中文件的解压缩 压缩文件的方法: //将工程中picture添加到左面111.zip压缩文件中 如果崩溃请更换压缩路径 -(void)testZipFile{ //压 ...

  3. iOS swift objc_setAssociatedObject和objc_getAssociatedObject使用

    oc中的AssociationsManager在swift中也是可以实现的 使用方法请看下面一个例子 import UIKit extension UIButton { func fk_addActi ...

  4. OpenCv for Android 环境搭建

    最近工作需要这样的功能 如下图 要在类似功能在android上实现 然后实现成这样 这两张图来自博客:图像校正—透视变换 可惜他用的是C/C++语言写的调用opencv,我参考了下他写的方案就想到了a ...

  5. Java中的使用了未经检查或不安全的操作(类前加:@SuppressWarnings("unchecked"))

    Java中的使用了未经检查或不安全的操作 如此解决就可以了 类前面加@SuppressWarnings("unchecked") @SuppressWarnings("u ...

  6. Linux3_文件系统

    1.Linux发行版本之间的差别很少,差别主要表现在系统管理的特色工具以及软件包管理方式的不同.目录结构基本上都是一样的. Windows的文件结构是多个并列的树状结构,最顶部的是不同的磁盘(分区), ...

  7. PHP fsockopen模拟POST/GET方法

    原文链接:http://www.nowamagic.net/academy/detail/12220214 fsockopen 除了前面小节的模拟生成 HTTP 连接之外,还能实现很多功能,比如模拟  ...

  8. [学英语]vocabulary.com你都可以怎么用

    vocabulary.com你都可以怎么用? 核心就是背单词. 1.利用纯英文环境熟悉单词,看看他们是如何解释单词的. 2.对于大段的文章,可以提炼出你需要背的单词. 3.以游戏的方式来背单词,app ...

  9. 记录-spring MultipartFile 文件上传

    注意:以下上传和下载方法未必完全正确,不同浏览器效果不同,建议不要使用IE /** * 简单的文件上传 * @author:qiuchen * @createTime:2012-6-19 * @par ...

  10. 配置过滤器filter对跨站脚本攻击XSS实现拦截

    1.web.xml中配置filter [html] view plain copy   <filter> <filter-name></filter-name> & ...