题链:

http://codeforces.com/contest/293/problem/E
题解:

点分治,树状数组
大致思路和 POJ 1741 那道点分治入门题相同,
只是因为多了一个路径的边数限制,
所以在统计答案时,
要用数据结构维护一下在满足距离限制的情况下,有多少点也满足边数限制。
树状数组维护到当前的根(重心)的距离为x时的点的个数。
在calc函数中,记录dep[u]表示u到当前的根(重心)的边数,
然后统计u号点可以和多少点组成合法点对时,就查询树状数中有多少点满足到根的距离小于等于W-dep[u].(W是输入的边数限制)

代码:

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
typedef pair<int,int>pii;
struct EDGE{
int ent;
int to[MAXN*2],nxt[MAXN*2],val[MAXN*2],head[MAXN];
void Reset(){ent=2; memset(head,0,sizeof(head));}
void Adde(int u,int v,int w){
to[ent]=v; val[ent]=w; nxt[ent]=head[u]; head[u]=ent++;
to[ent]=u; val[ent]=w; nxt[ent]=head[v]; head[v]=ent++;
}
}E;
struct BIT{
int val[MAXN],N;
int Lowbit(int x){return x&-x;}
void Reset(int n){
N=n+1; //memset(val,0,sizeof(val));
}
void Modify(int p,int x){
p++; for(;p<=N;p+=Lowbit(p)) val[p]+=x;
}
int Query(int p){
static int ans; ans=0; p++;
for(;p;p-=Lowbit(p)) ans+=val[p];
return ans;
}
}DT;
int N,K,W;
long long ANS;
int size[MAXN];
bool vis[MAXN];
void getroot(int u,int dad,int num,int &root,int &rootnum){
int maxnum=0; size[u]=0;
for(int i=E.head[u];i;i=E.nxt[i]){
if(E.to[i]==dad||vis[E.to[i]]) continue;
getroot(E.to[i],u,num,root,rootnum);
size[u]+=size[E.to[i]];
maxnum=max(maxnum,size[E.to[i]]);
}
size[u]++; maxnum=max(maxnum,num-size[u]);
if(maxnum<rootnum) root=u,rootnum=maxnum;
}
long long calc(int s,int len,int deep){
long long ret=0;
static pii A[MAXN];
static int dis[MAXN],dep[MAXN],reach[MAXN],rnt,ant;
static queue<int>Q;
ant=0; rnt++; Q.push(s);
dis[s]=len; reach[s]=rnt; dep[s]=deep;
while(!Q.empty()){
int u=Q.front(); Q.pop();
A[++ant]=make_pair(dis[u],dep[u]);
for(int i=E.head[u];i;i=E.nxt[i]){
int v=E.to[i];
if(reach[v]==rnt||vis[v]) continue;
dis[v]=dis[u]+E.val[i];
dep[v]=dep[u]+1;
reach[v]=rnt; Q.push(v);
}
}
sort(A+1,A+ant+1);
for(int i=1;i<=ant;i++) DT.Modify(A[i].second,1);
int l=1,r=ant;
while(l<=r){
if(A[l].first+A[r].first>K) DT.Modify(A[r].second,-1),r--;
else DT.Modify(A[l].second,-1),ret+=(W-A[l].second>=0?DT.Query(W-A[l].second):0),l++;
}
return ret;
}
void divide(int u){
int root=u,rootnum=size[u];
getroot(u,0,size[u],root,rootnum);
vis[root]=1;
ANS+=calc(root,0,0);
for(int i=E.head[root];i;i=E.nxt[i]) if(!vis[E.to[i]])
ANS-=calc(E.to[i],E.val[i],1);
for(int i=E.head[root];i;i=E.nxt[i]) if(!vis[E.to[i]])
divide(E.to[i]);
}
void read(int &x){
static int sign; static char ch;
x=0; sign=1; ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-')sign=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*sign;
}
int main(){
read(N); read(W); read(K);
E.Reset(); DT.Reset(N); ANS=0;
for(int i=2,dad,w;i<=N;i++)
read(dad),read(w),E.Adde(dad,i,w);
size[1]=N; divide(1);
cout<<ANS<<endl;
return 0;
}

  

●CodeForce 293E Close Vertices的更多相关文章

  1. codeforces 293E Close Vertices

    题目链接 正解:点分治+树状数组. 点分治板子题,直接点分以后按照$w$排序,扫指针的时候把$w$合法的路径以$l$为下标加入树状数组统计就行了. 写这道题只是想看看我要写多久..事实证明我确实是老年 ...

  2. CF 293E Close Vertices——点分治

    题目:http://codeforces.com/contest/293/problem/E 仍旧是点分治.用容斥,w的限制用排序+两个指针解决, l 的限制就用树状数组.有0的话就都+1,相对大小不 ...

  3. CodeForces 293E Close Vertices 点分治

    题目传送门 题意:现在有一棵树,每条边的长度都为1,然后有一个权值,求存在多少个(u,v)点对,他们的路劲长度 <= l, 总权重 <= w. 题解: 1.找到树的重心. 2.求出每个点到 ...

  4. 强连通分量&hdu_1269&Codeforce 369D

    强连通分量 标签: 图论 算法介绍 还记得割点割边算法吗.回顾一下,tarjan算法,dfs过程中记录当前点的时间戳,并通过它的子节点的low值更新它的low,low值是这个点不通过它的父亲节点最远可 ...

  5. Codeforce - Street Lamps

    Bahosain is walking in a street of N blocks. Each block is either empty or has one lamp. If there is ...

  6. Codeforce#331 (Div. 2) A. Wilbur and Swimming Pool(谨以此题来纪念我的愚蠢)

    C time limit per test 1 second memory limit per test 256 megabytes input standard input output stand ...

  7. Codeforce Round #216 Div2

    e,还是写一下这次的codeforce吧...庆祝这个月的开始,看自己有能,b到什么样! cf的第二题,脑抽的交了错两次后过了pretest然后system的挂了..脑子里还有自己要挂的感觉,果然回头 ...

  8. dataStructure@ Find if there is a path between two vertices in a directed graph

    Given a Directed Graph and two vertices in it, check whether there is a path from the first given ve ...

  9. cf293E Close Vertices(树分治+BIT)

    E. Close Vertices You've got a weighted tree, consisting of n vertices. Each edge has a non-negative ...

随机推荐

  1. 高校学生征信系统Postmortem结果

    Postmortem结果 设想和目标 1 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件需要解决的问题是当前高校学生征信系统建设薄弱的问题,我们试图建立 ...

  2. django搭建web (四) models.py

    demo 该demo模型主要是用于问题,选择单个或多个答案的问卷形式应用 # -*- coding: utf-8 -*- from __future__ import unicode_literals ...

  3. Hibernate之深入持久化对象

    Hibernate是一个彻底的O/R Mapping 框架.之所以说彻底,是因为相对于其他的 框架 ,如Spring JDBC,iBatis 需要手动的管理SQL语句,Hibernate采用了完全 面 ...

  4. L2 约束的最小二乘学习法

    \[ \begin{align*} &J_{LS}{(\theta)} = \frac { 1 }{ 2 } { \left\| \Phi \theta - y \right\| }^{ 2 ...

  5. 2018年东北农业大学春季校赛-wyh的吃鸡

    BFS: 1. 从起点开始BFS,遇到X点则return: 2. vis[px][py][0]代表经过pxpy这点前还没有找到车: vis[px][py][1]代表经过pxpy这点前已经找到车: 3. ...

  6. mongo数据库的常见操作

    连接mongodb数据库的命令查看对应数据库mongo.exeuse shujukuming;db.opportunity.findOne({"id":5}); db.opport ...

  7. 数据结构-线性表的链式存储相关算法(C语言实现)

    链表的简单介绍 为什么需要线性链表 当然是为了克服顺序表的缺点,在顺序表中,做插入和删除操作时,需要大量的移动元素,导致效率下降. 线性链表的分类 按照链接方式: 按照实现角度: 线性链表的创建和简单 ...

  8. ArrayList源码学习----JDK1.7

    什么是ArrayList? ArrayList是存储一组数据的集合,底层也是基于数组的方式实现,实际上也是对数组元素的增删改查:它的主要特点是: 有序:(基于数组实现) 随机访问速度快:(进行随机访问 ...

  9. Gitlab的安装及项目新建

    1. Gitlab的安装及仓库创建 1.1下载gitlab安装包 1).官网下载速度较慢 建议先行下载 国内的源里面可以找到最新的版本https://mirrors.tuna.tsinghua.edu ...

  10. HTML中的上下标标签的演示

    HTML中的上下标标签的演示 #table_head>td { font-weight: bold } tr { text-align: center } 作用 标签 演示代码 呈现效果 上标 ...