SPOJ Query on a tree V
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N. We define dist(a, b) as the number of edges on the path from node a to node b.
Each node has a color, white or black. All the nodes are black initially.
we will ask you to perfrom some instructions of the following form:
0 i : change the color of i-th node(from black to white, or from white to black).
1 v : ask for the minimum dist(u, v), node u must be white(u can be equal to v). Obviously, as long as node v is white, the result will always be 0.
Input
In the first line there is an integer N (N <= 100000)
In the next N-1 lines, the i-th line describes the i-th edge: a line with two integers a b denotes an edge between a and b.
In the next line, there is an integer Q denotes the number of instructions (Q <= 100000)
In the next Q lines, each line contains an instruction "0 i" or "1 v"
Output
For each "1 v" operation, print one integer representing its result. If there is no white node in the tree, you should write "-1".
Example
解题报告:
写了这个题之后算是对点分治有了个新认识,感觉以前写的都是假的啊.
突然发现任意两个点之间的路径仿佛都只会交在一个重心上,这样我们就很好弄了,对每一个重心维护一个小根堆,如果0操作弄出一个白点,我们就把这个白点加入到包含它的重心所在的堆里面,然后询问就直接查询包含该点的重心,用\(disi,v+q[i].top()\)去更新答案,i为某重心,q为该重心的堆,复杂度\(O(nlog2n)\)
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=100005,inf=2e8;
int gi(){
int str=0;char ch=getchar();
while(ch>'9' || ch<'0')ch=getchar();
while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
return str;
}
int n,num=0,head[N],to[N<<1],nxt[N<<1],root=0,f[N]={inf},son[N],sum;
bool vis[N];
struct node{
int x,id;
bool operator <(const node &pp)const{
return x>pp.x;
}
};
priority_queue<node>q[N];
void link(int x,int y){
nxt[++num]=head[x];to[num]=y;head[x]=num;
}
int Head[N],NUM=0,To[N*30],Dis[N*30],Next[N*30];
void add(int x,int y,int z){
Next[++NUM]=Head[x];To[NUM]=y;Dis[NUM]=z;Head[x]=NUM;
}
bool col[N];
void getdis(int x,int last,int dist){
add(x,root,dist);
int u;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==last || vis[u])continue;
getdis(u,x,dist+1);
}
}
void getroot(int x,int last){
int u;son[x]=1;f[x]=0;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(vis[u] || u==last)continue;
getroot(u,x);
son[x]+=son[u];
f[x]=Max(f[x],son[u]);
}
f[x]=Max(f[x],sum-son[x]);
if(f[x]<f[root])root=x;
}
void dfs(int x){
int u;vis[x]=true;
getdis(x,x,0);
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(vis[u])continue;
root=0;sum=son[u];getroot(u,x);
dfs(root);
}
}
void updata(int x){
col[x]^=1;
if(col[x])
for(int i=Head[x];i;i=Next[i])
q[To[i]].push((node){Dis[i],x});
}
int query(int x){
if(col[x])return 0;
int ret=inf;
for(int i=Head[x];i;i=Next[i]){
int u=To[i];
while(!q[u].empty() && !col[q[u].top().id])q[u].pop();
if(!q[u].empty())ret=Min(ret,q[u].top().x+Dis[i]);
}
return ret==inf?-1:ret;
}
void work()
{
int x,y;
n=gi();
for(int i=1;i<n;i++){
x=gi();y=gi();
link(x,y);link(y,x);
}
sum=n;root=0;getroot(1,1);
dfs(root);
int Q=gi(),flag;
while(Q--){
flag=gi();x=gi();
if(!flag)updata(x);
else printf("%d\n",query(x));
}
}
int main()
{
work();
return 0;
}
SPOJ Query on a tree V的更多相关文章
- 2019.02.17 spoj Query on a tree V(链分治)
传送门 题意简述: 给你一棵nnn个黑白点的树,初始全是黑点. 现在支持给一个点换颜色或者求整颗树中离某个点最近的白点跟这个点的距离. 思路: 考虑链分治维护答案,每个链顶用一个堆来维护答案,然后对于 ...
- QTREE5 - Query on a tree V——LCT
QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...
- SPOJ QTREE Query on a tree V
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...
- SPOJ QTREE Query on a tree V ——动态点分治
[题目分析] QTREE4的弱化版本 建立出分治树,每个节点的堆表示到改点的最近白点距离. 然后分治树上一直向上,取min即可. 正确性显然,不用担心出现在同一子树的情况(不会是最优解),请自行脑补. ...
- SPOJ - QTREE5 Query on a tree V 边分治
题目传送门 题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少. 题解: 这里用的还是边分治的方法. 把所有东西都抠 ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- Spoj Query on a tree III
题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...
- SPOJ Query on a tree III (树剖(dfs序)+主席树 || Splay等平衡树)(询问点)
You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose ...
- SPOJ QTREE4 SPOJ Query on a tree IV
You are given a tree (an acyclic undirected connected graph) with N nodes, and nodes numbered 1,2,3. ...
随机推荐
- 为label或者textView添加placeHolder
Tip:使用textView的代理需要在头文件中加入: <UITextViewDelegate> h文件 @interface FeedbackViewController : UIVie ...
- 使用 PHP 来做 Vue.js 的 SSR 服务端渲染
对于客户端应用来说,服务端渲染是一个热门话题.然而不幸的是,这并不是一件容易的事,尤其是对于不用 Node.js 环境开发的人来说. 我发布了两个库让 PHP 从服务端渲染成为可能.spatie/se ...
- 如何进行服务器Linux系统下的ext文件系统修复
一.故障描述 服务器是dell 730系列服务器,存储阵列是MD3200系列存储5T的Lun,操作系统是Linux centos 7,文件系统类型是EXT4,因意外断电,导致系统不能正常启动,修复之后 ...
- nyoj 黑色帽子
黑色帽子 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 最近发现了一个搞笑的游戏,不过目前还没玩过.一个舞会上,每个人头上都戴着一顶帽子,帽子只有黑 ...
- 在WebStorm中启动Angular项目
点击配置 创建 选择命令 package.json 运行 查看运行结果
- linux——网络基础
装完linux系统要对网络(ip地址,子网掩码,网关,DNS)进行配置,才能连接网络 一,开启网卡eth0 CentOS显示没有网卡(eth0) 2.设置静态IP vim /etc/sysconfig ...
- js jquery 获取元素(父节点,子节点,兄弟节点),元素筛选
转载:https://www.cnblogs.com/ooo0/p/6278102.html js jquery 获取元素(父节点,子节点,兄弟节点) 一,js 获取元素(父节点,子节点,兄弟节点) ...
- spring data redis template GenericJackson2JsonRedisSerializer的使用
配置 <!-- redis template definition --> <bean id="myRedisTemplate" class="org. ...
- *args和**kwargs
#coding=utf8 __author__ = 'Administrator' # 当函数的参数不确定时,可以使用*args和**kwargs.*args没有key值,**kwargs有key值 ...
- Java-Maven(五):Eclipse&Maven下创建java工程&web工程
本章文章主要学习集成了maven插件的eclipse下,创建java project和web project的步骤. 创建java工程 第一步:使用使用maven project来创建java pr ...