bzoj2599: [IOI2011]Race(点分治)
写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= =
点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对。
这道题要求距离等于K的点对中连接两点的最小边数。
那么其实道理是一样的。先找重心,然后先从重心开始求距离dis和边数num,更新ans,再从重心的儿子开始求得dis和num,减去这部分答案
因为这部分的答案中,从重心开始的两条链有重叠部分,所以要剪掉
基本算是模板题,但是减去儿子的答案的那部分还有双指针那里调了好久,所以还不算特别熟练。。
PS跑了27秒慢到飞起,不过代码短一点,看起来比较清晰
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
;
struct node{
int to,next,cost;
}e[maxn*];
struct data{
int l,e;
}dis[maxn];
];
void insert(int u, int v, int w){
e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].cost=w;
}
void getroot(int u, int f){
; size[u]=;
for (int i=head[u],v; i; i=e[i].next){
if (vis[v=e[i].to] || v==f) continue;
getroot(v,u);
size[u]+=size[v];
mx=max(mx,size[v]);
}
mx=max(mx,total-size[u]);
if (mx<sz) sz=mx,root=u;
}
void getdis(int u, int f, int len, int num){
dis[++p].l=len; dis[p].e=num;
for (int i=head[u],v; i; i=e[i].next){
if (vis[v=e[i].to] || v==f) continue;
getdis(v,u,len+e[i].cost,num+);
}
}
bool cmp(data a, data b){
if (a.l==b.l) return a.e<b.e; return a.l<b.l; /////
}
void count(int u, int len, int num, int f){
p=; getdis(u,,len,num); //这里要将len和num传下去。。
,r=p;
sort(dis+,dis++p,cmp);
while (l<=r){ //注意这里要用<=,WA了几发
while (l<r && dis[l].l+dis[r].l>K) r--;
for (int k=r; dis[l].l+dis[k].l==K; k--) ans[dis[l].e+dis[k].e]+=f;
l++;
}
}
void work(int u){
total=size[u]?size[u]:n;
sz=INF;
getroot(u,); u=root;
vis[u]=; count(u,,,);
for (int i=head[u],v; i; i=e[i].next){
if (vis[v=e[i].to]) continue;
count(v,e[i].cost,,-);
work(v);
}
}
int main(){
scanf("%d%d", &n, &K);
,u,v,w; i<n; i++) scanf("%d%d%d", &u, &v, &w),u++,v++,insert(u,v,w),insert(v,u,w);
work();
; i<n; i++) ;} puts("-1");
;
}
bzoj2599: [IOI2011]Race(点分治)的更多相关文章
- [bzoj2599][IOI2011]Race——点分治
Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...
- BZOJ2599:[IOI2011]Race(点分治)
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- 【BZOJ-2599】Race 点分治
2599: [IOI2011]Race Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 2590 Solved: 769[Submit][Status ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- [IOI2011]Race 点分治
[IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...
- [luogu4149][bzoj2599][IOI2011]Race【点分治】
题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...
- bzoj2599/luogu4149 [IOI2011]Race (点分治)
点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...
- 2019.01.09 bzoj2599: [IOI2011]Race(点分治)
传送门 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 思路: 考虑点分治如何合并. 我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可. 代码: ...
- BZOJ2599 [IOI2011]Race 【点分治】
题目 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 输入格式 第一行 两个整数 n, k 第二..n行 每行三个整 ...
随机推荐
- c/c++的Soap应用
1. 关于soap 在许多项目中团队中,我们常常会听到这样的话:我们这里是用webservice交互的.而说话的场景往往就是交互对象双方比较异构,所谓异构.即双方是不同的开发语言.不同的运行环境等.比 ...
- 解决fedora25安装vmware12问题:
运行vmware需要几个工具.gcc 编译工具是必须要有的.dnf groupinstall “Development tools“rpm -qa |grep kernel-headersrpm -q ...
- 【转】Caffe初试(八)Blob,Layer和Net以及对应配置文件的编写
深度网络(net)是一个组合模型,它由许多相互连接的层(layers)组合而成.Caffe就是组建深度网络的这样一种工具,它按照一定的策略,一层一层的搭建出自己的模型.它将所有的信息数据定义为blob ...
- 1280*720P和1920*1080P的视频在25帧30帧50帧60帧时的参数
- 【React】组件生命周期
初始化阶段 getDefaultPropos:只调用一次,实力之间共享引用 getInitialState:初始化每个实例特有的状态 componentWillMount:render之前最后一次修改 ...
- Python 学习笔记(6)--常用模块(2)
一.下载安装 下载安装有两种方式: yum\pip\apt-get 或者源码 下载源码 解压源码 进入目录 编译源码 python setup.py build 安装源码 python setup.p ...
- 3小时搞定一个简单的MIS系统案例Northwind,有视频、有源代码下载、有真相
一.瞎扯框架.架构 楼主自从1998年从C语言.MASM.Foxbase开始学计算机开始接触这个行当16年以来,2001年干第一份与程序.软件.然后是各种屌的东西开始,差不多干了13年了,这13年来, ...
- lua
lua的语言特性: 1. lua 的table可以实现多种数据结构:数组.记录.线性表.队列.集合等: 2. lua的closure闭合函数 3. lua的迭代器和泛型的for 4. lua的协同程序 ...
- php操作mysql
- R语言绘制空间热力图
先上图 R语言的REmap包拥有非常强大的空间热力图以及空间迁移图功能,里面内置了国内外诸多城市坐标数据,使用起来方便快捷. 开始 首先安装相关包 install_packages("dev ...