Codeforce 342 E. Xenia and Tree 解析(思維、重心剖分)

今天我們來看看CF342E

題目連結

題目

給你一棵樹,有兩種操作,把某點標成紅色或者查詢離某點最近的紅點有多遠。

前言

這題我是當作學習重心剖分的習題看待的,最詳細的版本請看教學文

想法

每兩個樹上的點,其重心剖分樹(CD樹)上的\(LCA\)一定在其最短路徑上。因此當我們把點\(v\)塗成紅色時,我們只需要更改CD樹上\(v\)的祖先到最近的紅點的距離就好。

令\(ans[v]\)代表\(v\)子樹(CD樹上的子樹)上到離\(v\)最近的紅點的距離。假設把\(v\)塗色,\(j\)為\(v\)在CD樹上的某個祖先,\(ans[j]=min(ans[j],dist(v,j))\),\(dist(v,j)\)代表在原圖上\(v,j\)間的最短距離,我們可以用老方法:\(dist(v,j)=dep[v]+dep[j]-2\times dep[lca(v,j)]\),\(dep[v]\)是\(v\)在原圖的深度。

而要搜尋離\(v\)最近的紅點距離時,由於兩點間的最短距離上一定有CD樹上\(v\)的祖先,因此我們遍歷那些祖先(點\(j\)),找\(dist(v,j)+ans[j]\)的最小值。

程式碼:

const int _n=1e5+10;
int t,n,m,aa,bb,vv,ans[_n];
VI G[_n];
int sz[_n],cd_fa[_n];
bool del[_n];
void dfsSz(int v,int faa){
sz[v]=1;
rep(i,0,SZ(G[v]))if(G[v][i]!=faa and !del[G[v][i]])dfsSz(G[v][i],v),sz[v]+=sz[G[v][i]];
}
int get_centroid(int v,int faa,int cnt){
rep(i,0,SZ(G[v]))if(G[v][i]!=faa and !del[G[v][i]] and sz[G[v][i]]>cnt/2)
return get_centroid(G[v][i],v,cnt);
return v;
}
void centroid_decomposition(int v,int faa){
dfsSz(v,faa);int centroid=get_centroid(v,faa,sz[v]);
cd_fa[centroid]=faa,del[centroid]=1;
rep(i,0,SZ(G[centroid]))if(G[centroid][i]!=faa and !del[G[centroid][i]])
centroid_decomposition(G[centroid][i],centroid);
}
const int MAXB=18;
int dep[_n],fa[_n][MAXB];
void dfs(int v,int faa,int d){
dep[v]=d;fa[v][0]=faa;
rep(i,0,SZ(G[v]))if(faa!=G[v][i])dfs(G[v][i],v,d+1);
}
void bfa(){
rep(j,1,MAXB)rep(i,1,n+1)if(~fa[i][j-1])
fa[i][j]=fa[fa[i][j-1]][j-1];
}
int lca(int a,int b){
if(dep[a]<dep[b])swap(a,b);
per(j,0,MAXB)if(~fa[a][j] and dep[fa[a][j]]>=dep[b])a=fa[a][j];
if(a==b)return a;
per(j,0,MAXB)if(~fa[a][j] and fa[a][j]!=fa[b][j])a=fa[a][j],b=fa[b][j];
return fa[a][0];
}
void update(int vv){
int b=vv;
while(b!=-1){
int l=lca(vv,b);
ans[b]=min(ans[b],dep[vv]+dep[b]-2*dep[l]);
b=cd_fa[b];
}
}
main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;rep(i,0,n-1){cin>>aa>>bb;G[aa].pb(bb),G[bb].pb(aa);}
dfs(1,-1,0);rep(i,1,n+1)rep(j,1,MAXB)fa[i][j]=-1; bfa();
centroid_decomposition(1,-1);rep(i,1,n+1)ans[i]=1e5;
update(1);
while(m--){
cin>>t>>vv;
if(t==1)update(vv);
else{
int minn=1e9,b=vv;
while(b!=-1){
int l=lca(vv,b);
minn=min(minn,ans[b]+dep[b]+dep[vv]-2*dep[l]);
b=cd_fa[b];
}cout<<minn<<'\n';
}
}
return 0;
}

標頭、模板請點Submission看

Submission

E. Xenia and Tree 解析(思維、重心剖分)的更多相关文章

  1. D. Maximum Distributed Tree 解析(思維、DFS、組合、貪心、DP)

    Codeforce 1401 D. Maximum Distributed Tree 解析(思維.DFS.組合.貪心.DP) 今天我們來看看CF1401D 題目連結 題目 直接看原題比較清楚,略. 前 ...

  2. B. Kay and Snowflake 解析(思維、DFS、DP、重心)

    Codeforce 685 B. Kay and Snowflake 解析(思維.DFS.DP.重心) 今天我們來看看CF685B 題目連結 題目 給你一棵樹,要求你求出每棵子樹的重心. 前言 完全不 ...

  3. E. Tree Queries 解析(思維、LCA)

    Codeforce 1328 E. Tree Queries 解析(思維.LCA) 今天我們來看看CF1328E 題目連結 題目 給你一棵樹,並且給你\(m\le2e5\)個詢問(包含\(k\)個點) ...

  4. E. Tree Reconstruction 解析(思維)

    Codeforce 1041 E. Tree Reconstruction 解析(思維) 今天我們來看看CF1041E 題目連結 題目 略,請直接看原題 前言 一開始完全搞錯題目意思,還以為每次會刪除 ...

  5. A. Arena of Greed 解析(思維)

    Codeforce 1425 A. Arena of Greed 解析(思維) 今天我們來看看CF1425A 題目連結 題目 略,請直接看原題. 前言 明明是難度1400的題目,但總感覺不是很好寫阿, ...

  6. E. Almost Regular Bracket Sequence 解析(思維)

    Codeforce 1095 E. Almost Regular Bracket Sequence 解析(思維) 今天我們來看看CF1095E 題目連結 題目 給你一個括號序列,求有幾個字元改括號方向 ...

  7. C2. Power Transmission (Hard Edition) 解析(思維、幾何)

    Codeforce 1163 C2. Power Transmission (Hard Edition) 解析(思維.幾何) 今天我們來看看CF1163C2 題目連結 題目 給一堆點,每兩個點會造成一 ...

  8. F. Moving Points 解析(思維、離散化、BIT、前綴和)

    Codeforce 1311 F. Moving Points 解析(思維.離散化.BIT.前綴和) 今天我們來看看CF1311F 題目連結 題目 略,請直接看原題. 前言 最近寫1900的題目更容易 ...

  9. B. Two Arrays 解析(思維)

    Codeforce 1417 B. Two Arrays 解析(思維) 今天我們來看看CF1417B 題目連結 題目 略,請直接看原題. 前言 a @copyright petjelinux 版權所有 ...

随机推荐

  1. 一款Java开源的Springboot即时通讯 IM,附源码

    # 开篇 电商平台最不能缺的就是即时通讯,例如通知类下发,客服聊天等.今天,就来给大家分享一个开源的即时通讯系统.如对文章不感兴趣可直接跳至文章末尾,有获取源码链接的方法. 但文章内容是需要你简单的过 ...

  2. element弹框的的this.$alert、this.$prompt方法用法

    调用$alert方法即可打开消息提示,它模拟了系统的 alert,无法通过按下 ESC 或点击框外关闭 调用$prompt方法即可打开消息提示,它模拟了系统的 prompt

  3. Android小部件Widget开发过程中的坑和总结

    @ 目录 概述 官方参考 效果图 AndroidManifest.xml Receiver Service Options res/xml/ widget_desktop_options.xml 常用 ...

  4. 删除链表的倒数第N个节点(头部加一个哑结点)

    我的代码:测试用例[1,2]2,  时会报错,无法不能删除第一个指针 /** * Definition for singly-linked list. * public class ListNode ...

  5. 坐标下降(Coordinate descent)

    坐标下降法属于一种非梯度优化的方法,它在每步迭代中沿一个坐标的方向进行线性搜索(线性搜索是不需要求导数的),通过循环使用不同的坐标方法来达到目标函数的局部极小值.

  6. RT Thread的SPI设备驱动框架的使用以及内部机制分析

    注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...

  7. Asp.Net Core 企业微信静默授权

    企业微信接口文档 1.构造授权网页链接 2.回调获取到 Code 通过code+access_token去请求用户信息 3.获取access_token 调试准备工作 -->内网穿透+域名 推荐 ...

  8. 029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑“非”运算符

    029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑"非"运算符 本文知识点:Java中的逻辑"非"运算符 逻辑& ...

  9. Noip 2013 真题练习

    Day1 T1 转圈游戏 Link 一句话题意: 让你求 \({x + m \times 10^k} \bmod n\) 的结果. 直接套上快速幂的板子. code #include<iostr ...

  10. 看动画学算法之:linkedList

    目录 简介 linkedList的构建 linkedList的操作 头部插入 尾部插入 中间插入 删除节点 简介 linkedList应该是一种非常非常简单的数据结构了.节点一个一个的连接起来,就成了 ...