BZOJ 2599 [IOI2011]Race【Tree,点分治】
给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数。
点分治,这道题目和POJ 2114很接近,2114是求是否存在长度为K的边,但是那个K比较大。但是这道题目的K比之小了10倍。
1. 用V[i]表示到当前树根root的路径长度为i 时的点(赋值为root结点即可),这样就可以用来判断两条到根的路径长度之和是否等于K:
结点a的root的距离为i,结点b到root的距离为j,处理完a之后会得到V[i] = root,那么在处理结点b的时候,如果V[K-j] = root,就说明某一个a和b的路径长度为K,此时,就可以更新最小边数了。
2. e[i]表示到当前树根root的路径长度为i 时的边的最小条数。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
#define N 200010
#define inf 0x3f3f3f3f
struct node {
int v, l;
node() {}
node(int _v, int _l): v(_v), l(_l) {};
};
vector<node> g[N];
int n, K, cur, root, size, ans;
int s[N], f[N], d[N], e[N]; //s子树的结点数,f求重心,d子结点到根的距离,e子结点到根的边数
int v[N*10], c[N*10];
bool done[N]; void getroot(int now, int fa) {
int u;
s[now] = 1, f[now] = 0;
for (int i=0; i<g[now].size(); i++)
if ((u = g[now][i].v) != fa && !done[u]) {
getroot(u, now);
s[now] += s[u];
f[now] = max(f[now], s[u]);
}
f[now] = max(f[now], size-s[now]);
if (f[now] < f[root]) root = now;
}
void dfs1(int now, int fa) {
if (d[now] > K) return ;
if (v[K-d[now]] == cur) ans = min(ans, c[K-d[now]]+e[now]);
int u;
for (int i=0; i<g[now].size(); i++)
if ((u = g[now][i].v) != fa && !done[u]) {
d[u] = d[now] + g[now][i].l;
e[u] = e[now] + 1;
dfs1(u, now);
}
}
void dfs2(int now, int fa) {
if (d[now] > K) return ;
if (v[d[now]] != cur) {
c[d[now]] = e[now];
v[d[now]] = cur;
} else c[d[now]] = min(c[d[now]], e[now]);
int u;
for (int i=0; i<g[now].size(); i++)
if ((u = g[now][i].v) != fa && !done[u])
dfs2(u, now);
}
void work(int now) {
v[0] = cur = now + 1;
int u;
for (int i=0; i<g[now].size(); i++)
if (!done[u = g[now][i].v]) {
d[u] = g[now][i].l;
e[u] = 1;
dfs1(u, now);
dfs2(u, now);
}
getroot(now, n); //更新s数组
done[now] = true;
for (int i=0; i<g[now].size(); i++)
if (!done[u = g[now][i].v]) {
f[n] = size = s[u];
getroot(u, root=n);
work(root);
}
}
int main() {
scanf("%d%d", &n, &K);
for (int i=0; i<=n; i++) g[i].clear(); for (int i=1, a, b, c; i<n; i++) {
scanf("%d%d%d", &a, &b, &c);
g[a].push_back(node(b, c));
g[b].push_back(node(a, c));
}
memset(done, false, sizeof(done)); ans = f[n] = size = n;
getroot(0, root=n);
work(root); printf("%d\n", ans < n ? ans : -1); return 0;
}
BZOJ 2599 [IOI2011]Race【Tree,点分治】的更多相关文章
- bzoj 2599 [IOI2011]Race (点分治)
[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...
- bzoj 2599: [IOI2011]Race【点分治】
点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- bzoj 2599 [IOI2011]Race 点分
[IOI2011]Race Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 4768 Solved: 1393[Submit][Status][Dis ...
- bzoj 2599: [IOI2011]Race (点分治 本地过了就是过了.jpg)
题面:(复制别人的...) Description 给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的 ...
- 【刷题】BZOJ 2599 [IOI2011]Race
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- BZOJ 2599: [IOI2011]Race
点分治,定权值,求另一关键字最小 不满足前缀加减性 可以按序遍历,用一数组$t[] 来维护路径为i的最小边数$ 再对于一个直系儿子对应的子树,先算距离求答案再更新$t数组,这样就不会重复$ #incl ...
- 2599: [IOI2011]Race
2599: [IOI2011]Race 链接 分析 被memset卡... 点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少.然后先遍历子树,更新答 ...
- 【BZOJ】2599: [IOI2011]Race 点分治
[题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...
随机推荐
- C#共享内存类改进版
原文 C#共享内存类改进版 改进说明及源码实例下载见:http://blog.csdn.net/zzh8845/archive/2008/11/22/3349963.aspx ShareMem.cs ...
- 深入分析MySQL ERROR 1045 (28000)
这几天在MySQL新建用户后.出现訪问拒绝的问题,错误码为ERROR 1045(28000).在网上搜索了非常久.找到了非常多解决的方法,但非常遗憾的是这么多办法没有一个能解决该问题.尽管出现的错误码 ...
- Compare the value of entity field.
public class Program { static void Main(string[] args) { Program p = new Program(); p.Test(); Consol ...
- Orchard站点性能优化-预热
Orchard CMS 包含一个 Warmup Module 模块,当我们的站点在共享主机上的时候,它可以显著的帮助我们快速响应用户访问请求.当你开启这个模块以后,你设置的URL的里面的内容会缓存起来 ...
- C# Best Practices - Specify Clear Method Parameters
Improve parameters parameter order public OperationResult PlaceOrder(Product product, int quantity, ...
- POJ 3903 Stock Exchange (E - LIS 最长上升子序列)
POJ 3903 Stock Exchange (E - LIS 最长上升子序列) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action ...
- [条款36]绝不重新定义继承而来的non-virtual函数
看下面的两个类的声明代码: class B { public: void mf(); //something to do }; class D : public B { public: void mf ...
- C#学习日记之数据库连接
一.webconfig设置和参数解释 在C#中新建一个网站时,webconfig文件中会有一个默认的数据库连接语句,如下 <connectionStrings> <add name= ...
- Nginx阅读笔记(四)之root和alias
nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应.root与alias主要区别在于nginx如何解释location后面的uri ...
- KbmMW资源汇总(更新中…)
KbmMW框架是收费的,不在此提供下载,如需购买,请自行联系作者Kim Madsen. 网址资源: 官网主页:http://www.components4programmers.com/product ...