POJ 3162 - Walking Race(树形DP)
来源:互联网 发布:软件自动汉化工具 编辑:程序博客网 时间:2024/06/14 03:38
题目:
http://poj.org/problem?id=3162
题意:
树中节点的直径,最大值与最小值的差值不超过m的最大区间。
思路:
步骤1:求树的直径。
步骤2:求出区间,维护两个单调队列,一个递增一个递减。
AC.
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1e6+5;int n, m;int tol, head[maxn];struct Edge{ int to, w, next;}edge[maxn*2];void addedge(int u, int v, int w){ edge[tol].to = v; edge[tol].w = w; edge[tol].next = head[u]; head[u] = tol++;}int dis[maxn], dson[maxn], pre[maxn];int d[maxn];void dfs(int u, int fa){ int tmp = 0; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(v == fa) continue; dfs(v, u); dson[u] = max(dson[u], dson[v] + w); }}void dfs1(int u, int fa){ int max1 = 0, max2 = 0, tmp; int v1; int v, w; for(int i = head[u]; ~i; i = edge[i].next) { v = edge[i].to; w = edge[i].w; if(v == fa) continue; tmp = dson[v] + w; if(tmp > max1) { max2 = max1; max1 = tmp; v1 = v; } else if(tmp == max1 || tmp > max2) { max2 = tmp; } } if(u != 1) { tmp = dis[u]; v = -1; if(tmp > max1) { max2 = max1; max1 = tmp; v1 = v; } else if(max1 == tmp || tmp > max2) max2 = tmp; } for(int i = head[u]; ~i; i = edge[i].next) { v = edge[i].to; w = edge[i].w; if(v == fa) continue; if(v == v1) dis[v] = max2+w; // printf("v= %d: %d\n", v, dis[v]); else dis[v] = max1+w; // printf("**v= %d: %d\n", v, dis[v]); dfs1(v, u); }}int qmax[maxn], qmin[maxn];void solve(){ int ans = 1; int s = 1,t = 1; int t1=1, t2=1, i1=1, i2=1; qmax[t1++] = d[1]; qmin[t2++] = d[1]; while(t < n) { if(qmax[i1] - qmin[i2] <= m) { t++; int tmp = d[t]; while(i1 < t1 && qmax[t1-1] < tmp) t1--; qmax[t1++] = tmp; while(i2 < t2 && qmin[t2-1] > tmp) t2--; qmin[t2++] = tmp; } else { int tmp = d[s++]; if(qmax[i1] == tmp) i1++; if(qmin[i2] == tmp) i2++; } if(qmax[i1] - qmin[i2] <= m) { //printf("%d %d: ", qmax[i1], qmin[i2]); //printf("(%d, %d)\n", s, t); ans = max(ans, t-s+1); } } printf("%d\n", ans);}void init(){ tol = 0; memset(head, -1, sizeof(head)); memset(dis, 0, sizeof(dis)); memset(d, 0, sizeof(d)); memset(dson, 0, sizeof(dson)); memset(qmax, 0, sizeof(qmax)); memset(qmin, 0, sizeof(qmin));}int main(){ //freopen("inn", "r", stdin); while(~scanf("%d%d", &n, &m)) { init(); for(int u = 2; u <= n; ++u) { int v, w; scanf("%d%d", &v, &w); addedge(u, v, w); addedge(v, u, w); } dfs(1, -1); dfs1(1, -1); for(int i = 1; i <= n; ++i) { //printf("%d %d: ", dson[i], dis[i]); d[i] = max(dson[i], dis[i]); // printf("%d\n", d[i]); } solve(); } return 0;}
0 0
- POJ 3162 Walking Race 树形DP
- POJ 3162 Walking Race (树形DP)
- POJ 3162 - Walking Race(树形DP)
- POJ 3162 Walking Race(树形DP+单调队列)
- POJ 3162 Walking Race(树形DP + 单调队列)
- poj 3162 walking race 树形dp 求符合条件区间
- poj 3162 Walking Race 树形dp + 单调队列
- 【树形DP】Poj 3162 Walking Race (DP_树形DP(线段树))
- POJ 3162Walking Race( 树形dp+线段树处理区间)
- POJ 3162 Walking Race——树形dp+尺取+线段树
- poj 3162 Walking Race
- poj 3162 Walking Race
- POJ 3162 Walking Race
- 解题报告:POJ 3162 Walking Race 树型DP+单调RMQ
- POJ 3162 Walking Race 笔记
- POJ 3162(TreeDP+单调队列)Walking Race
- POJ 3162 Walking Race (DFS + 线段树)
- POJ 3162 Walking Race (单调队列)@
- bzoj-1488 图的同构
- KMP算法详解
- [leetcode] 23.Merge k Sorted Lists
- 1098 -- 计算平均数
- muduo网络库源码学习————无界队列和有界队列
- POJ 3162 - Walking Race(树形DP)
- 1099 -- 温度转化
- 精通Hibernate——级联操纵对象
- 循环-01. 求整数段和(15)
- Java栈的实例-数组和链表两种方法
- 1235:统计同成绩学生人数
- Apache与Tomcat
- C源码@数据结构与算法->DisjointSet
- 小而精,小而美的一款开源的迷你框架Underscore.js