bzoj 2599(点分治)
2599: [IOI2011]Race
Time Limit: 70 Sec Memory Limit: 128 MB
Submit: 3642 Solved: 1081
[Submit][Status][Discuss]
Description
给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000
Input
第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)
Output
一个整数 表示最小边数量 如果不存在这样的路径 输出-1
Sample Input
0 1 1
1 2 2
1 3 4
Sample Output
/*
开一个100W的数组t,t[i]表示权值为i的路径最少边数
找到重心分成若干子树后, 得出一棵子树的所有点到根的权值和x,到根a条边,用t[k-x]+a更新答案,全部查询完后
然后再用所有a更新t[x]
这样可以保证不出现点分治中的不合法情况
把一棵树的所有子树搞完后再遍历所有子树恢复T数组,如果用memset应该会比较慢
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> #define inf 1000000000
#define maxn 1000005
#define maxx 200005 using namespace std; int n,K,cnt,sum,root,ans,x,y,z;
int tot[maxn],head[maxx],son[maxx],f[maxx],dis[maxx],d[maxx];
bool vis[maxx];
struct edge
{
int to,next,w;
}e[maxx<<]; inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} void add(int u,int v,int w)
{
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
} void get_root(int now,int fa)
{
son[now]=;f[now]=;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa&&!vis[v])
{
get_root(v,now);
son[now]+=son[v];f[now]=max(f[now],son[v]);
}
}
f[now]=max(f[now],sum-son[now]);
if(f[now]<f[root]) root=now;
} void cal(int now,int fa)
{
if(dis[now]<=K) ans=min(ans,d[now]+tot[K-dis[now]]);
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v]&&v!=fa)
{
d[v]=d[now]+;
dis[v]=dis[now]+e[i].w;
cal(v,now);
}
}
} void updata(int now,int fa,int flag)
{
if(dis[now]<=K)
{
if(flag) tot[dis[now]]=min(tot[dis[now]],d[now]);
else tot[dis[now]]=inf;
}
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v]&&v!=fa)
updata(v,now,flag);
}
} void work(int now)
{
vis[now]=;tot[]=;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
{
d[v]=;dis[v]=e[i].w;
cal(v,);updata(v,,);
}
}
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
updata(v,,);//去掉重心之后要重新统计
}
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
{
root=;sum=son[v];
get_root(v,);
work(root);
}
}
} int main()
{
n=read();K=read();
for(int i=;i<=K;i++)tot[i]=n;
for(int i=;i<n;i++)
{
x=read();y=read();z=read();
x++;y++;
add(x,y,z);add(y,x,z);
}
ans=sum=f[]=n;get_root(,);
work(root);
if(ans!=n)printf("%d\n",ans);
else puts("-1");
return ;
}
bzoj 2599(点分治)的更多相关文章
- bzoj 2599 数分治 点剖分
具体可以见漆子超的论文 /************************************************************** Problem: User: B ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- 【BZOJ 2599】【IOI 2011】Race 点分治
裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...
- bzoj 2599 [IOI2011]Race (点分治)
[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...
- BZOJ 2599 Race(树分治)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 题意:每次 ...
- 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【点分治】
点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...
- 【刷题】BZOJ 2599 [IOI2011]Race
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
随机推荐
- 5.C#编写Redis访问类
那么通过前面几篇博文,服务端的安装和配置应该没什么问题了,接下来的问题是如何通过代码来访问Redis. 这里我们使用的库为: StackExchange.Redis GitHub:https://gi ...
- Node.js概述
Node.js最重要的特性:通过单线程实现异步处理环境 Node.js解决的问题: Node.js修改了客户端连接服务器端的连接方法,不需要为每个客户端连接创建一个新的线程,而是为每个客户端连接触发一 ...
- Android中Adapter和Bridge模式理解和应用
一 Adapter模式 意图: 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作. 适用性: 使用一个已存在的类,而它的接口 ...
- __declspec(dllexport)
__declspec(dllexport) (2010-06-17 10:04:28) 转载▼ 标签: __declspec dllexport 导出 it 分类: C 先看代码:以下是在dev-c+ ...
- CAD取Excel表格(com接口)
1 2 3 4 5 6 7 8 9 10 11 12 MxDrawResbuf ret = (MxDrawResbuf)axMxDrawX1.Call("ExApp_GetExcel&quo ...
- centos7安装个人网盘owncloud
现在个人资料越来越重要,网络速度也已经满足日常需要,网盘已经是生活着存取个人数据不可缺少的工具. 下面在linxu centos7下面安装owncloud搭建自己私人网盘: 1.新建一个账号用来安装个 ...
- snprintf不能使用"字符串指针"赋值,可以使用字符数组
#cat snprintf.c #include <stdio.h> #include <stdlib.h> #include <string.h> struct ...
- c/c++排坑(2) -- c语言中的符号重载
所谓的符号重载就是在不同的上下文环境里有不同的意义.甚至有些关键字也被重载而具有好几种意义,这也是C语言的作用域规则对程序员不那么清晰的主要原因. 本章内容摘自<c专家编程>P37. 大家 ...
- HDU-5968异或密码
超级传送门 题目描述: 晨晨在纸上写了一个长度为N的非负整数序列{ai}.对于这个序列的一个连续子序列{al,al+1,…,ar}晨晨可以求出其中所有数异或的结果 alxoral+1xor...xor ...
- flask中的session cookie 测试 和 项目中的用户状态保持
# -*- coding:utf-8 -*- # Author: json_steve from flask import Flask, current_app, make_response, req ...