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的更多相关文章

  1. BZOJ 2599: [IOI2011]Race( 点分治 )

    数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...

  2. bzoj 2599 [IOI2011]Race 点分

    [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 4768  Solved: 1393[Submit][Status][Dis ...

  3. bzoj 2599 [IOI2011]Race (点分治)

    [题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...

  4. BZOJ 2599 [IOI2011]Race【Tree,点分治】

    给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数. 点分治,这道题目和POJ 2114很接近,2114是 ...

  5. bzoj 2599: [IOI2011]Race (点分治 本地过了就是过了.jpg)

    题面:(复制别人的...) Description 给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的 ...

  6. 【刷题】BZOJ 2599 [IOI2011]Race

    Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...

  7. 【BZOJ】2599: [IOI2011]Race 点分治

    [题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...

  8. BZOJ 2599: [IOI2011]Race

    点分治,定权值,求另一关键字最小 不满足前缀加减性 可以按序遍历,用一数组$t[] 来维护路径为i的最小边数$ 再对于一个直系儿子对应的子树,先算距离求答案再更新$t数组,这样就不会重复$ #incl ...

  9. bzoj 2599: [IOI2011]Race【点分治】

    点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...

随机推荐

  1. [原创] Debian9上配置Samba

    Samba概述 Samba是一套使用SMB(Server Message Block)协议的应用程序,通过支持这个协议,Samba允许Linux服务器与Windows系统之间进行通信,使跨平台的互访成 ...

  2. U深度U盘启动盘制作工具怎么用?U深度U盘启动盘制作工具使用教学

    U深度u盘启动盘制作工具是一款强大的启动盘制作软件,对于新手用户来说,由于软件专业度很高,想一下就上手是比较困难的.所以这里给大家分享一篇U深度u盘启动盘制作工具的使用教程. 使用教程: 第一步:安装 ...

  3. Vim中修改列模式的文字为ABCD或1234的递增序号

    vimrc里添加 vnoremap <F3> :<C-u>call <SID>AddCharOfCursor()<CR> "递增列模式下的字符 ...

  4. Js parsetInt() 字符串转换,只能转换字符串,数字开头的才会返回数值,否则为NaN,空字符串也返回NaN

    alert(parseInt('456lee')); //456,返回正数部分 alert(parseInt('lee456lee')); //NaN alert(parseInt('lee456le ...

  5. 矩阵连乘的相乘次数(ZOJ1094)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=94 解题报告: 1.数据结构: ///矩阵行数和列数 struct N ...

  6. 2018.7.6 js实现点击事件---点击小图出现大图---时间定时器----注册表单验证

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  7. PowerDesigner生成sql脚本

    1.打开PowerDesigner->New Project; 2.填写项目名称,选择文件的存放路径: 3.新建一个模型,New Model: 4.选择概念模型,填写模型名称: 5.选择enti ...

  8. Java删除文件或目录及目录下所有文件

    一直在做C++相关开发的工作.突然某一天一时兴起,想学习下Java开发.然后再网上找到一本Java简明教程,入门是够用了.看到文件IO这一章,想起之前用C++做的删除文件或目录的练习,于是打算用Jav ...

  9. hdu 2828 Buy Tickets

    Buy Tickets Time Limit : 8000/4000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total ...

  10. linux mysql5.7 安装、 开机启动

    一.安装 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz h ...