POJ 3162 Walking Race——树形dp+尺取+线段树
来源:互联网 发布:淘宝收获日面具 编辑:程序博客网 时间:2024/06/18 14:54
RMQ蜜汁MLE??可能是写挫了,不过尺取+线段是nlogn就过了
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 1e6 + 10;int n, m, tot, head[maxn], dp[maxn][3], x[maxn];struct Edge { int to, cost, next;}edge[maxn<<1];void init() { tot = 0; memset(head, -1, sizeof(head));}void addedge(int u, int v, int cost) { ++tot; edge[tot].to = v, edge[tot].cost = cost, edge[tot].next = head[u]; head[u] = tot;}void dfs1(int u, int p) { for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (v == p) continue; dfs1(v, u); } int pos = 0; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to, cost = edge[i].cost; if (v == p) continue; if (dp[u][0] < dp[v][0] + cost) { dp[u][0] = dp[v][0] + cost; pos = v; } } for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to, cost = edge[i].cost; if (v == p || v == pos) continue; dp[u][1] = max(dp[u][1], dp[v][0] + cost); }}void dfs2(int u, int p) { for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to, cost = edge[i].cost; if (v == p) continue; dp[v][2] = max(dp[u][2], ((dp[v][0] + cost == dp[u][0]) ? dp[u][1] : dp[u][0])) + cost; dfs2(v, u); }}struct SegTree { int val[2][maxn<<2]; void pushup(int root) { val[0][root] = max(val[0][root<<1], val[0][root<<1|1]); val[1][root] = min(val[1][root<<1], val[1][root<<1|1]); } void build(int l, int r, int root) { if (l == r) { val[0][root] = max(dp[l][0], dp[l][2]); val[1][root] = max(dp[l][0], dp[l][2]); return; } int mid = (l + r)>>1; build(l, mid, root<<1); build(mid + 1, r, root<<1|1); pushup(root); } int query(int l, int r, int root, int ql, int qr, int index) { if (ql <= l && r <= qr) return val[index][root]; int mid = (l + r)>>1; int ans; if (index == 0) ans = 0; else ans = INF; if (ql <= mid) { if (index == 0) { ans = max(ans, query(l, mid, root<<1, ql, qr, index)); } else { ans = min(ans, query(l, mid, root<<1, ql, qr, index)); } } if (mid < qr) { if (index == 0) { ans = max(ans, query(mid + 1, r, root<<1|1, ql, qr, index)); } else { ans = min(ans, query(mid + 1, r, root<<1|1, ql, qr, index)); } } return ans; }}segtree;int solve() { for (int i = 1; i <= n; i++) x[i] = max(dp[i][0], dp[i][2]); int l = 1, r = 0, maxv = 0, minv = INF, ans = 0; for (int i = 1; i <= n; i++) { r++; maxv = max(maxv, x[i]), minv = min(minv, x[i]); while (l <= r && maxv - minv > m) { l++; maxv = segtree.query(1, n, 1, l, r, 0); minv = segtree.query(1, n, 1, l, r, 1); } ans = max(ans, r - l + 1); } return ans;}int main() { int v, cost; while (~scanf("%d %d", &n, &m)) { init(); for (int i = 1; i <= n - 1; i++) { scanf("%d %d", &v, &cost); addedge(i + 1, v, cost); addedge(v, i + 1, cost); } memset(dp, 0, sizeof(dp)); dfs1(1, -1); dfs2(1, -1); segtree.build(1, n, 1); printf("%d\n", solve()); } return 0;}
阅读全文
1 0
- 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 (树形DP)
- POJ 3162 - Walking Race(树形DP)
- POJ 3162 Walking Race (DFS + 线段树)
- POJ 3162 Walking Race(树形DP+单调队列)
- POJ 3162 Walking Race(树形DP + 单调队列)
- poj 3162 walking race 树形dp 求符合条件区间
- poj 3162 Walking Race 树形dp + 单调队列
- POJ 3162 Walking Race 树的直径+线段树
- poj 3162 Walking Race
- poj 3162 Walking Race
- POJ 3162 Walking Race
- POJ 3162 Walking Race(单调队列或线段树加树型DP)
- 解题报告:POJ 3162 Walking Race 树型DP+单调RMQ
- POJ 3162 Walking Race 笔记
- 流程图解Spring Framework(九) Spring 如何进行事务管理的?
- MySQL存储过程与触发器(应用场景)
- PriorityBlockingQueue
- offee
- Eclipse安装插件地址集合
- POJ 3162 Walking Race——树形dp+尺取+线段树
- 第七节 使用matplotlib可视化数据
- java中i++ ++i字节码解释
- HTML+CSS+JS实现轮播效果
- java中输出格式,包括四舍五入的实例
- 流程图解Spring Framework(十) Spring MVC如何根据请求匹配处理的?
- centos7.3下用户和组的管理
- 买到首批iPhone X的用户先别高兴,刘海体验不佳
- 二叉树的实现与基本操作(C指针实现)