2599: [IOI2011]Race
2599: [IOI2011]Race
分析
被memset卡。。。
点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少。然后先遍历子树,更新答案,然后在遍历一边更新T,防止出现两个起点在同一棵子树中的情况。
代码
#include<cstdio>
#include<algorithm>
#include<cctype> using namespace std; const int N = ;
const int INF = 1e9; struct Edge{
int to,nxt,w;
Edge() {}
Edge(int a,int b,int c) {to = a,w = b,nxt = c;}
}e[N<<];
int head[N],siz[N],T[];
bool vis[N];
int n,k,tot,Size,Num,Root,Ans = N; inline int read() {
int x = ,f = ;char ch=getchar();
for (; !isdigit(ch); ch=getchar()) if(ch=='-')f=-;
for (; isdigit(ch); ch=getchar()) x=x*+ch-'';
return x*f;
}
void add_edge(int u,int v,int w) {
e[++tot] = Edge(v,w,head[u]);head[u] = tot;
e[++tot] = Edge(u,w,head[v]);head[v] = tot;
}
void getRoot(int u,int fa) {
siz[u] = ;
int mx = ;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v == fa || vis[v]) continue;
getRoot(v,u);
siz[u] += siz[v];
mx = max(siz[v],mx);
}
mx = max(Size-siz[u],mx);
if (mx < Num) Root = u,Num = mx;
}
void dfs1(int u,int fa,int L,int C) {
if (L > k) return ;
Ans = min(Ans,T[k-L]+C);
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v == fa || vis[v]) continue;
dfs1(v,u,L+e[i].w,C+);
}
}
void dfs2(int u,int fa,int L,int C,int f) {
if (L > k) return ;
if (f) T[L] = min(T[L],C);
else T[L] = INF;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v == fa || vis[v]) continue;
dfs2(v,u,L+e[i].w,C+,f);
}
}
void calcc(int u) {
T[] = ;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (vis[v]) continue;
dfs1(v,u,e[i].w,);
dfs2(v,u,e[i].w,,);
}
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (vis[v]) continue;
dfs2(v,u,e[i].w,,);
}
}
void solve(int u) {
vis[u] = true;
calcc(u);
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (vis[v]) continue;
Size = siz[v],Root = ,Num = 1e9;
getRoot(v,);
solve(Root);
}
}
int main() {
n = read(),k = read();
for (int i=; i<=k; ++i) T[i] = INF;
for (int u,v,w,i=; i<n; ++i) {
u = read(),v = read(),w = read();
add_edge(u+,v+,w);
if (w == k) {printf("-1");return ;}
}
Size = n;Num = 1e9;
getRoot(,);
solve(Root);
if (Ans == N) puts("-1");
else printf("%d",Ans);
return ;
}
2599: [IOI2011]Race的更多相关文章
- 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 (点分治)
[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...
- BZOJ 2599 [IOI2011]Race【Tree,点分治】
给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数. 点分治,这道题目和POJ 2114很接近,2114是 ...
- 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 点分治
[题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...
- BZOJ 2599: [IOI2011]Race
点分治,定权值,求另一关键字最小 不满足前缀加减性 可以按序遍历,用一数组$t[] 来维护路径为i的最小边数$ 再对于一个直系儿子对应的子树,先算距离求答案再更新$t数组,这样就不会重复$ #incl ...
- bzoj 2599: [IOI2011]Race【点分治】
点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...
随机推荐
- 关于 supersocket 不能通过Bootstrap 启动
App.config内容 <configSections> <section name="superSocket" type="SuperSocke ...
- python3绘图示例4(基于matplotlib:箱线图、散点图等)
#!/usr/bin/env python# -*- coding:utf-8 -*- from matplotlib.pyplot import * x=[1,2,3,4]y=[5,4,3,2] # ...
- jupyter notebook 报错 ImportError: No module named matplotlib
解决办法: 打开Anaconda Prompt 列出conda环境: conda info --envs 结果显示: # conda environments: # tensorflow * D:\ ...
- 在windows bat脚本(batch)中延时
编写bat脚本时,有事我们希望在指令和指令之间,加入延时.例如当一条指令执行后,windows需要一定时间来响应的情况. 以下是一种实现方法,通过ping 指令来实现,5表示ping5次,就是延时5秒 ...
- gcc常用参数列举
[参数详解] -c 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件 例子用法: gcc -c hello.c 他将生成.o的obj文件 -S 只激活预处理和编译,就是指 ...
- eclipse快捷键(个人经常使用的)
周末闲来无聊,就把一直以来eclipse使用的快捷键梳理了下,希望对有需要的朋友有所帮助,绝对原创! 1.快速复制一行或者多行 首先选中你要复制的行,如果是一行,则鼠标焦点在那一行即可,如果是多行,可 ...
- Android(java)学习笔记59:类继承的 注意事项
1. 类继承的注意事项: /* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. ...
- ELF文件格式与进程地址空间的联系
http://blog.csdn.net/q_l_s/article/details/52597330 三.分析在fork产生新进程中ELF文件格式与进程地址空间的联系 1.进程的虚拟地址空间 每个程 ...
- Linux 初学者:移动文件
你学习了有关目录和访问目录的权限是如何工作的.你在这些文章中学习的大多数内容都可应用于文件 -- Paul Brown 在之前的该系列的部分中, 你学习了有关目录 和 访问目录 的权限 是如何工作的. ...
- 2018.7.19 . php复习
PHP程序设计 1.请写出HTML标记meta的完整英文单词:metadata 2.相当于http文件头作用(向浏览器传回正确和精确地显示网页内容的消息)的meta标记的属性是http-equiv 3 ...