POJ 3162 Walking Race (树形DP)
2015-07-17 13:03
309 查看
这个题的关键点在于怎么求出上下界<=M的最大区间。
思路:先像上一篇一样求出每个点到达的最大距离,用mlen[]记录下来。
然后用multiset去维护区间的最大值和最小值,因为multiset是升序的。
复杂度O(nlogn)
我的代码:
思路:先像上一篇一样求出每个点到达的最大距离,用mlen[]记录下来。
然后用multiset去维护区间的最大值和最小值,因为multiset是升序的。
复杂度O(nlogn)
我的代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> using namespace std; const int maxn = 1000005; struct Nod{ int b,val,next; void init(int b,int val,int next){ this->b=b;this->val=val;this->next=next; } }buf[maxn<<1]; int len,E[maxn]; int n,m,dp[maxn][3]; int mlen[maxn]; multiset<int> ms; multiset<int>::iterator o1,o2; void init(){ len = 0;ms.clear(); memset(E,-1,sizeof(E)); memset(dp,0,sizeof(dp)); memset(mlen,0,sizeof(mlen)); } void add_Edge(int a,int b,int val){ buf[len].init(b,val,E[a]);E[a]=len++; buf[len].init(a,val,E[b]);E[b]=len++; } void dfs(int u,int pre){ int v,cost,i; for(i = E[u] ; i != -1 ; i = buf[i].next){ v = buf[i].b;cost = buf[i].val; if(v == pre) continue; dfs(v,u); if(dp[u][0] < dp[v][0] + cost){ dp[u][1] = dp[u][0]; dp[u][0] = dp[v][0] + cost; }else if(dp[u][1] < dp[v][0] + cost) dp[u][1] = dp[v][0] + cost; } } void ndfs(int u,int pre){ int dist,i; for(i = E[u]; i != -1 ; i = buf[i].next) if(buf[i].b == pre){ dist = buf[i].val;break; } if(pre != -1){ if(dp[u][0] + dist == dp[pre][0]){ dp[u][2] = dist + max(dp[pre][1],dp[pre][2]); }else dp[u][2] = dist + max(dp[pre][0],dp[pre][2]); } for(i = E[u] ; i != -1 ; i = buf[i].next) if(buf[i].b != pre) ndfs(buf[i].b,u); } void solve(){ dfs(1,-1); ndfs(1,-1); int i,l,r,low,ans = 0; for(i = 1 ;i <= n ;i++) mlen[i] = max(dp[i][0],dp[i][2]); for(r = 1 ;r <= n ;r++){ if(ms.empty()) { ms.insert(mlen[r]); l = r; } else{ o1 = ms.begin();o2 = ms.end();o2--; if(mlen[r] > *o1 + m || mlen[r] < *o2 - m){ r--; ms.erase(ms.find(mlen[l])); l++; }else{ ms.insert(mlen[r]); } } ans = max(ans,(int)ms.size()); } printf("%d\n",ans); } int main(){ init(); scanf("%d%d",&n,&m); int f,d; for(int i = 2; i <= n ; i++){ scanf("%d%d",&f,&d); add_Edge(i,f,d); } solve(); return 0; }
相关文章推荐
- Android开发工具之ADT
- 【南阳OJ分类之大数问题】题目+AC代码汇总
- hdu 5073 Galaxy(2014acm鞍山亚洲分部 D)
- GRE写作必备句型
- 数字滤波器的时域理解
- Java类加载器架构
- shell(1)
- C++ 全局对象构造和析构
- 深入理解JavaScript系列(4):立即调用的函数表达式
- Linux全栈工程师--传智播客C++公开课之全栈工程师修成记
- Android开发UI之ViewPager及PagerAdapter
- 如何在shell下使用JavaScript和Mongodb交互?
- protel 99se :format %x invalid or incompatible with argument
- 深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
- Project Euler:Problem 70 Totient permutation
- ACM--Doing Homework again(贪心算法)
- 收集几个不错的最新win10系统64位和32位系统Ghost版下载
- 医疗信息季节:入口划分医疗领域
- 深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)
- 使用pb的connection对象建立TCP连接