博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2599: [IOI2011]Race [点分治]
阅读量:6705 次
发布时间:2019-06-25

本文共 2783 字,大约阅读时间需要 9 分钟。

2599: [IOI2011]Race

Time Limit: 70 Sec  Memory Limit: 128 MB
Submit: 3069  Solved: 898
[][][]

Description

给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000

 

Input

第一行 两个整数 n, k

第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3
0 1 1
1 2 2
1 3 4

Sample Output

2

小总结:

目前遇到的点分治处理有两种:

1.先统计每颗子树,处理一颗子树时使用了之前子树的信息

2.先统计整棵树然后减去同一棵子树里的,可以只一遍邻接链表循环

 

对于本题,

1.可以用d[i]表示之前遍历过的子树中深度为i的最小边数,c[i]表示i到根的边数

然后点分治时,一个个子树遍历,先更新答案在用更新d[],再一遍遍历把d[]复原(不能用memset,复杂度...)

注意:每次dfsSol里都要d[0]=0,难道有w=0的边?!

2.还可以用那种排序的方法,不过区间min不支持减法,所以记录每种边数出现的次数,就可以减了....

注意:排序往里扫的时候是l<=r,为什么啊?明明同一个点,我太弱了不知道为什么

 

ps:1比2快了10ms

#include
#include
#include
#include
#include
using namespace std;const int N=2e5+5,K=1e6+5,INF=1e9;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f;}int n,k,u,v,w;struct edge{ int v,w,ne;}e[N<<1];int h[N],cnt;inline void ins(int u,int v,int w){ cnt++; e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt; cnt++; e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;}int size[N],f[N],rt,vis[N],sum;void dfsRt(int u,int fa){ size[u]=1;f[u]=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(vis[v]||v==fa) continue; dfsRt(v,u); size[u]+=size[v]; f[u]=max(f[u],size[v]); } f[u]=max(f[u],sum-size[u]); if(f[u]

 

#include
#include
#include
#include
#include
using namespace std;const int N=2e5+5,K=1e6+5,INF=1e9;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f;}int n,k,u,v,w;struct edge{ int v,w,ne;}e[N<<1];int h[N],cnt;inline void ins(int u,int v,int w){ cnt++; e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt; cnt++; e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;}int size[N],f[N],rt,vis[N],sum;void dfsRt(int u,int fa){ size[u]=1;f[u]=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(vis[v]||v==fa) continue; dfsRt(v,u); size[u]+=size[v]; f[u]=max(f[u],size[v]); } f[u]=max(f[u],sum-size[u]); if(f[u]
k) r--; int i=r; while(a[l].deep+a[i].deep==k) ans[a[l].c+a[i].c]+=v,i--; l++; }}void dfsSol(int u){ //printf("dfsSol %d\n",u); vis[u]=1; cal(u,0,0,1); for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(vis[v]) continue; cal(v,e[i].w,1,-1); sum=size[v]; rt=0;dfsRt(v,0);v=rt; dfsSol(v); }}int main(){ //freopen("in.txt","r",stdin); n=read();k=read(); for(int i=1;i

 

 

 

 

 

 

转载地址:http://liflo.baihongyu.com/

你可能感兴趣的文章
python 读取SQLServer数据插入到MongoDB数据库中
查看>>
TCP的三次握手与四次挥手(详解+动图)
查看>>
Centos 6.5 磁盘修复 破解删除root密码
查看>>
某游戏浏览器Flash加速dll调用,打造我们自己的Flash加速器
查看>>
XML序列化与反序列化
查看>>
Redis数据操作命令
查看>>
java 注解
查看>>
DP(记忆化搜索) + AC自动机 LA 4126 Password Suspects
查看>>
2016"百度之星" - 资格赛(Astar Round1)
查看>>
批量修改横断面图高程范围
查看>>
Java高并发程序设计学习笔记(八):NIO和AIO
查看>>
java javax.annotation.Resource注解的详解
查看>>
lombok 介绍及基本使用方法
查看>>
mybatis的if标签判断子类属性-There is no getter for property named 'export' in
查看>>
static变量和方法
查看>>
过度自信是创业者的通行证
查看>>
关键字和保留字
查看>>
Springboot 图标更换
查看>>
HDU Problem 2546 饭卡【01背包】
查看>>
BS4
查看>>