Description

http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf

Input

Output

暑假集训的时候点分树做的比较少,所以做这道题比较吃力,然而现在看这道题就比较简单了.
考虑直接建立点分树,每一个节点只需维护点分子树中 $BFS$ 序.
这样的好处是子树中点的深度是连续的,所以每次能到达的点肯定是连续的区间.
那么,只需按照 $Dijkstra$ 的运行过程,将点加入到优先队列中,并扩展队首.
每次扩展只需边删掉 $BFS$ 序中可以到达的点并加入到堆中,然后一边跳点分树中父亲即可.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=300005;
namespace IO {
void setIO(string s) {
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {
int x=0;
char c=nc();
while(c<48) c=nc();
while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();
return x;
}
};
namespace tree{
int edges;
int hd[maxn],to[maxn<<1],nex[maxn<<1];
int fa[maxn],top[maxn],siz[maxn],son[maxn],dep[maxn];
void addedge(int u,int v) {
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs1(int u,int ff) {
dep[u]=dep[ff]+1,fa[u]=ff,siz[u]=1;
for(int i=hd[u];i;i=nex[i]) {
int v=to[i];
if(v==ff) continue;
dfs1(v,u), siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int tp) {
top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(int i=hd[u];i;i=nex[i]) {
int v=to[i];
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
int LCA(int x,int y) {
while(top[x]^top[y]) {
dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
}
return dep[x]<dep[y]?x:y;
}
int Dis(int x,int y) {
return dep[x]+dep[y]-(dep[LCA(x,y)]*2);
}
};
namespace Divide {
struct Node {
int dis,u;
Node(int dis=0,int u=0):dis(dis),u(u){}
}st[maxn],val[maxn*30];
queue<Node>q;
int mn,root,tp,edges;
int siz[maxn],mx[maxn],mark[maxn],Fa[maxn],in[maxn],hd[maxn],to[maxn*30],nex[maxn*30];
void Add(int u,Node e) {
nex[++edges]=hd[u],hd[u]=edges,val[edges]=e;
}
void getroot(int u,int ff) {
mx[u]=0, siz[u]=1;
for(int i=tree::hd[u];i;i=tree::nex[i]) {
int v=tree::to[i];
if(v==ff||mark[v]) continue;
getroot(v,u), siz[u]+=siz[v];
mx[u]=max(mx[u],siz[v]);
}
mx[u]=max(mx[u], mn-siz[u]);
if(mx[u] < mx[root]) root=u;
}
void bfs(int u) {
tp=0;
q.push(Node(0,u));
in[u]=u;
while(!q.empty()) {
Node e=q.front(); q.pop();
st[++tp]=e;
int x=e.u;
for(int i=tree::hd[x];i;i=tree::nex[i]) {
int v=tree::to[i];
if(mark[v]||in[v]==u) continue;
in[v]=u;
q.push(Node(e.dis+1,v));
}
}
for(int i=tp;i>=1;--i) Add(u, st[i]);
}
void divide(int u) {
mark[u]=1;
bfs(u);
for(int i=tree::hd[u];i;i=tree::nex[i]) {
int v=tree::to[i];
if(mark[v]) continue;
root=0,mn=siz[v],getroot(v,u);
Fa[root]=u;
divide(root);
}
}
void pre(int n) {
mx[0]=1000000000,mn=n,root=0,getroot(1,0);
divide(root);
}
};
int n,S;
int L[maxn];
ll C[maxn];
namespace Dijkstra {
ll d[maxn];
int flag[maxn];
struct Node {
ll dis;
int u;
Node(ll dis=0,int u=0):dis(dis),u(u){}
bool operator<(Node b) const {
return dis>b.dis;
}
};
priority_queue<Node>q;
void del(int x,int limit,ll ge,int u) {
if(limit<0) return;
while(Divide::hd[x] && Divide::val[Divide::hd[x]].dis<=limit) {
int v=Divide::val[Divide::hd[x]].u;
Divide::hd[x]=Divide::nex[Divide::hd[x]];
if(flag[v]) continue;
d[v]=ge, flag[v]=1, q.push(Node(d[v] + C[v], v));
}
if(Divide::Fa[x]) del(Divide::Fa[x],L[u]-tree::Dis(u,Divide::Fa[x]),ge,u);
}
void solve() {
d[S]=0,flag[S]=1;
q.push(Node(C[S],S));
while(!q.empty()) {
Node e=q.top(); q.pop();
del(e.u, L[e.u], e.dis, e.u);
}
}
};
int main() {
using namespace IO;
// setIO("input");
n=rd(),S=rd();
for(int i=1;i<n;++i) {
int u=rd(),v=rd();
tree::addedge(u,v);
tree::addedge(v,u);
}
tree::dfs1(1,0);
tree::dfs2(1,1);
for(int i=1;i<=n;++i) L[i]=rd(), C[i]=(ll)rd();
Divide::pre(n);
Dijkstra::solve();
for(int i=1;i<=n;++i) printf("%lld\n",Dijkstra::d[i]);
return 0;
}

  

BZOJ 5129: [Lydsy1712月赛]树上传送 点分树+Dijkstra的更多相关文章

  1. bzoj 5125: [Lydsy1712月赛]小Q的书架

    新学了一波 决策单调性 dp 套路.... 这种dp一般是长这样的 => f[i][j] = max/min  { f[i-1][k] + cost(k+1,j)} ,其中cost函数满足四边形 ...

  2. bzoj 5123: [Lydsy1712月赛]线段树的匹配

    设f[0/1][x]为区间[1,x]的根向下 不选(0)或者选(1)  的dp pair<最优值,方案数>. 可以很容易的发现总状态数就是log级别的,因为2*n 与 (2*n+1 或者 ...

  3. [BZOJ 5127][Lydsy1712月赛]数据校验

    Description 题库链接 给你一个长度为 \(n\) 的序列.\(m\) 次询问,每次询问序列的一个区间 \([l,r]\).对于 \([l,r]\) 内的所有子区间,询问值域是否连续.若存在 ...

  4. BZOJ 4881: [Lydsy1705月赛]线段游戏 动态规划 + 线段树

    Description quailty和tangjz正在玩一个关于线段的游戏.在平面上有n条线段,编号依次为1到n.其中第i条线段的两端点坐 标分别为(0,i)和(1,p_i),其中p_1,p_2,. ...

  5. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  6. BZOJ Lydsy5月月赛 ADG题解

    题目链接 BZOJ5月月赛 题解 好弱啊QAQ只写出三题 A 判断多干个数乘积是否是某个数的倍数有很多方法,比较常用的是取模,但这里并不适用,因为模数不定 会发现数都比较小,所以我们可以考虑分解质因子 ...

  7. KMP + BZOJ 4974 [Lydsy1708月赛]字符串大师

    KMP 重点:失配nxtnxtnxt数组 意义:nxt[i]nxt[i]nxt[i]表示在[0,i−1][0,i-1][0,i−1]内最长相同前后缀的长度 图示: 此时nxt[i]=jnxt[i]=j ...

  8. BZOJ 3924 / Luogu P3345 [ZJOI2015]幻想乡战略游戏 (动态点分治/点分树)

    题意 树的结构不变,每个点有点权,每一条边有边权,有修改点权的操作,设xxx为树中一点.求∑idist(x,i)∗a[i]\sum_idist(x,i)*a[i]i∑​dist(x,i)∗a[i]的最 ...

  9. 【BZOJ 3735】苹果树 树上莫队(树分块+离线莫队+鬼畜的压行)

    2016-05-09 UPD:学习了新的DFS序列分块,然后发现这个东西是战术核导弹?反正比下面的树分块不知道要快到哪里去了 #include<cmath> #include<cst ...

随机推荐

  1. Linux(Ubuntu)常用命令 & vim基本操作

    Linux先知: Linux历史: 关于这个我就不再多说了,其实是一个很有意思的故事串,网上找下一大堆. 类Unix系统目录结构: ubuntu没有盘符这个概念,只有一个根目录/,所有文件都在它下面 ...

  2. Django 优秀资源大全

    版权: https://github.com/haiiiiiyun/awesome-django-cn 转自:https://www.jianshu.com/p/38c4dd6d8e28 Awesom ...

  3. Java多线程学习——图片下载

    实现多线程方式1:继承类Thread——重写方法run——调用方法start 从网络下载图片首先要增加包commons-io.jar import org.apache.commons.io.File ...

  4. Window7系统安装和使用MySql

    win7系统MySql安装和使用教程 首先下载mysql安装包 点击下载mysql v5.7.1 解压 下载完毕后解压在D盘 路径为D:\mysql-5.7.13-winx64,然后进入这个目录,新建 ...

  5. 第二周JAVA总结

    学海无涯,在学习这件事情上得用点心了

  6. Cocos2d-x-javaScript 的webSocket的代码

    var WebSocket = WebSocket || window.WebSocket || window.MozWebSocket; var WebSocketManager = cc.Clas ...

  7. ExtensionlessUrlHandler-Integrated-4.0

    window 10 锁定webconfig解决方案 解决办法:  出现这个错误是因为 IIS 7 采用了更安全的 web.config 管理机制,默认情况下会锁住配置项不允许更改.要取消锁定可以以管理 ...

  8. html5移动端Meta的设置

    强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览 1 <meta name="viewport" content=&quo ...

  9. spark(3)

    0.spark -------------------------------------------- transformation map filter repartition spark核心AP ...

  10. SSM框架返回json数据

    常见错误:No converter found for return value of type: class .................. 原因分析:这是因为springmvc默认是没有对象 ...