题意:

  给你一棵树,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. struts2 拦截器,使用spring注入

    ActionContext actionContext = invocation.getInvocationContext();ServletContext context = (ServletCon ...

  2. Foundation框架 - NSDictionary类、NSMutableDictionary类

    NSArray.NSSet.NSDictionary /* 集合 1.NSArray\NSMutableArray * 有序 * 高速创建(不可变):@[obj1, obj2, obj3] * 高速訪 ...

  3. memcached使用总结

    我的linux版本信息:Linux version 4.4.0-78-generic (buildd@lgw01-11) (gcc version 5.4.0 20160609 (Ubuntu 5.4 ...

  4. Java -- 数字

    @.运用BigDecimal处理Double类型的算术运算的精度问题 原文:https://blog.csdn.net/j754379117/article/details/52238396 可使用 ...

  5. mysql主从实验

    实验一: 服务器A与服务器B是主从关系,关联的库有test1,.test2库,主从一直运行正常,此时由于业务的需求,需再增加test3库,并让其仍然维持主从关系,应该怎么做? 步骤一: 修改从库服务器 ...

  6. python 基础 9.5 数据库连接池

      一. 数据库连接池    python 编程中可以使用MySQLdb 进行数据库的连接及诸如查询,插入,更新等操作,但是每次连接mysql 数据库请求时,都是独立的去请求访问,相当浪费资源,而且访 ...

  7. iOS 推送跳转到相关页面

    哈哈哈 我又来窃取别人的劳动成果了 写的很好呦 http://www.jianshu.com/p/c0eb32443915

  8. 【python】-- web开发之JavaScript

    JavaScript JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. ...

  9. c#的const可以用于引用类型吗

    答案是可以的.不过用const修饰的类实例只能是null. class A{ public int a=0; } class B{ const A constA=null; const object ...

  10. importlib 模块导入

    #1.动态导入模块 script_name = scripts.utils module = importlib.import_module(script_name) # 动态导入相应模块 #2.模块 ...