黑白图

Problem Description

黑白图是一个由n个点和n-1条边组成的无向连通图。在图中最多只有一个节点的度会超过2,其余点的度要么为1,要么为2。一个节点的度指的是与该节点有边相连的节点的个数。图中的边是有颜色的,要么白色,要么黑色。一开始所有的边都是黑色。

对黑白图我们可以进行以下三种操作:

1)把第i条边变成黑色。第i条边是指在图中编号为i的边。(这里保证第i条边在变色前是白色的)

2)把第i条边变成白色。(这里保证第i条边在变色前是黑色的)

3)找出从点a到点b的最短路,并且在这条路上只有黑边。或者判断出a和b点之间不存在由黑边组成的路。

节点编号从1到n,边的编号从1到n-1。

样例解释:

在样例一中,1号点和2号点由1号边连接。2号点和3号点由2号边连接。在边被着色前,所有的点都是相互连通的。所以从1号点到3号点最短路是2。

如果我们把2号边变成白色,则3号点与其它点将不再连通。

Input

单组测试数据
第一行,有一个整数n(2≤n≤10^5) 表示图中点的个数。
接下来的n-1行表示边的信息。
每行用vi ui(1≤vi,ui≤n,vi≠ui)表示第i条边连接的两个点。
这里保证图一定是黑白图,并且没有自环和重边。

接下来一行,有一个整数m(1≤m≤3*10^5),表示对图进行操作的次数。
接下来有m行,每行用以下形式表示。
首先有一个整数type(1≤type≤3),表示操作的类型。

如果type=1,则表示要把某条变成黑色。这种情况下,后面会跟一个整数id(1≤id≤n-1),表示要变色的边的编号。

如果type=2,则表示要把某条变成白色。这种情况下,后面会跟一个整数id(1≤id≤n-1),表示要变色的边的编号。

如果type=3,则表示要查询两个点之间由黑边组成的最短距离。这种情况下,后面会跟两个整数a,b(1≤a,b≤n,a有可能等于b),表示要查询的两个节点的编号。
具体可参考测试用例。

每行输入中的整数都由一个空格隔开。
边按输入的顺序进行编号。

Output

对于每个type=3的操作,输出a到b的最短距离。
如果不存在从a到b由黑边组成的路径,则输出“-1”(没有引号)。
输出的相对顺序和输入的相对顺序相同。
每个操作输出占一行。

Sample Input

样例一
3
1 2
2 3
7
3 1 2
3 1 3
3 2 3
2 2
3 1 2
3 1 3
3 2 3
样例二
6
1 5
6 4
2 3
3 5
5 6
6
3 3 4
2 5
3 2 6
3 1 2
2 3
3 3 1

Sample Output

输出一
1
2
1
1
-1
-1
输出二
3
-1
3
2

题解:

一棵树,最多只有一个节点的度数超过2。显然将这个点(没有度数超过2的就随便选一个)作为根,这个点下面的每个子树都是链状。DFS将每个点重新编号,保证同一子树内编号连续,同时处理出每个点到根的距离。
利用树状数组维护一段连续编号内的黑点的数量,因为维护的是边的信息,而重新编号的是点,所以将一条边的两点中编号较大的那个点代表这条边,更新都对该点操作即可。如果LCA(u,v)是根,将其作为两条链即可。利用子树编号连续来判断链内黑边的数量即可。

#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-7using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 200100;
const int mod = 998244353;
int cnt, in[maxn], id[maxn], dis[maxn], rot[maxn], p[maxn];
int u[maxn], v[maxn];
vector<int> g[maxn];
int lowbit(int x);
int query(int x);
void Update(int x, int y, int n);
void dfs(int u, int rt, int fa, int d);int main()
{int n, m, i, j, k, op, be = -1;cnt = 2;scanf("%d", &n);for(i=2;i<=n;i++)Update(i, 1, n);for(i=1;i<n;i++){scanf("%d %d", &u[i], &v[i]);in[u[i]]++, in[v[i]]++;if(in[u[i]]>2)be = u[i];if(in[v[i]]>2)be = v[i];g[u[i]].push_back(v[i]);g[v[i]].push_back(u[i]);}if(be == -1)be = 1;id[be] = 1, rot[be]=2;for(i=0;i<g[be].size();i++)dfs(g[be][i], cnt, be, 1);scanf("%d", &m);while(m--){scanf("%d", &op);if(op == 1){scanf("%d", &i);j = max(id[u[i]], id[v[i]]);Update(j, -1, n);}else if(op ==2){scanf("%d", &i);j = max(id[u[i]], id[v[i]]);Update(j, 1, n);}else{int l, r;scanf("%d %d", &l, &r);if(rot[l] == rot[r]){if(id[l]>id[r])swap(l,r);if(id[r]-id[l] == query(id[r])-query(id[l]))printf("%d\n", dis[r]-dis[l]);else printf("-1\n");}else{if(id[r]-rot[r]+1+id[l]-rot[l]+1 == query(id[r])-query(rot[r]-1)+query(id[l])-query(rot[l]-1))printf("%d\n", dis[r]+dis[l]);else printf("-1\n");}}}return 0;
}int lowbit(int x)
{return x&(-x);
}void Update(int x, int y, int n)
{for(int i=x;i<=n;i+=lowbit(i))p[i] += y;
}int query(int x)
{int sum = 0;for(int i=x;i>0;i-=lowbit(i))sum += p[i];return sum;
}void dfs(int u, int rt, int fa, int d)
{id[u] = cnt++;rot[u] = rt;dis[u] = d;for(int i=0;i<g[u].size();i++)if(g[u][i] != fa){dfs(g[u][i], rt, u, d+1);}
}

51nod_1809 黑白图(DFS+树状数组)相关推荐

  1. 计蒜客-青出于蓝胜于蓝 dfs+树状数组

    题目描述: 武当派一共有 n人,门派内 n 人按照武功高低进行排名,武功最高的人排名第 1,次高的人排名第 2,... 武功最低的人排名第 n.现在我们用武功的排名来给每个人标号,除了祖师爷,每个人都 ...

  2. HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化

    题目链接 You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-neg ...

  3. 2016 大连网赛---Weak Pair(dfs+树状数组)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5877 Problem Description You are given a rooted ...

  4. CF Edu54 E. Vasya and a Tree DFS+树状数组

    Vasya and a Tree 题意: 给定一棵树,对树有3e5的操作,每次操作为,把树上某个节点的不超过d的子节点都加上值x; 思路: 多开一个vector记录每个点上的操作.dfs这颗树,同时以 ...

  5. HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...

  6. CodeForces - 1076E Vasya and a Tree 树剖?nono dfs+树状数组

    题目链接:https://cn.vjudge.net/problem/CodeForces-1076E 题解:树状数组维护下深度,到达每个节点,对于每次更新容斥一下,对于直接查询即可 #include ...

  7. malic-2021年寒假热身-05 D - 楼高莫近危阑倚(DFS+树状数组)

     记录入度,从而找到树的根结点,从根结点进行DFS,在向叶子结点搜索的时候将当前结点值加入树状数组,在回溯的时候再减去,这样每个子树就不会互相影响.. #include <iostream> ...

  8. 数据结构——树状数组

    我们今天来讲一个应用比较广泛的数据结构--树状数组 它可以在O(nlogn)的复杂度下进行单点修改区间查询,下面我会分成三个模块对树状数组进行详细的解说,分别是树状数组基本操作.树状数组区间修改单点查 ...

  9. 树状数组 数据结构详解与模板(可能是最详细的了)

    目录 转载请注明出处:bestsort.cn 树状数组基础 单点更新: 区间查询: 高级操作 求逆序对 操作 原理 求区间最大值 区间修改+单点查询 查询 修改 区间修改+区间查询 查询 修改 二维树 ...

最新文章

  1. Hibernate学习(九)———— 二级缓存和事务级别详讲
  2. 理解熵:机器学习的黄金标准
  3. 【Python】值得推荐的12个jupyter lab插件
  4. HLS Pargmas(2) interface
  5. java加密证书生成_mkcert 1.3.0 发布,本地 HTTPS 加密证书生成工具
  6. Maven学习总结(18)——深入理解Maven仓库
  7. 电脑黑屏的原因有哪些
  8. MobileNetV2: Inverted Residuals and Linear Bottlenecks
  9. 【Oracle】redo与undo
  10. CocurrentHashMap和Hashtable的区别
  11. UE4 视差毛发材质
  12. ESP8266/ESP8285 启动报错 csum err ets_main.c 解决办法
  13. OverFeat 详解
  14. HUAWEI 机试题:VLAN资源池
  15. 描绘新十年智慧生活蓝图,AWE2021圆满闭幕
  16. python自动化测试面试题None is ==详解
  17. java单链表反转(头插法)详解
  18. 长沙计算机学院王进,王进教授
  19. Q/W防洪跳转页面/微信小程序跳转到未备案域名
  20. 《禅与摩托车维修艺术》

热门文章

  1. 阿里版GPT官宣“阿里全家桶”:所有产品都将接入
  2. bluehost 虚拟主机 php.ini,BlueHost主机配置Php.ini中文解释(六)
  3. js事件委托和jQuery事件绑定on , off , one , bind , unbind , die
  4. libcurl 基础介绍
  5. react 编程式导航和声明式导航
  6. 朴素贝叶斯算法(带例题解释)
  7. java static 并发_Java static并发问题
  8. 一篇文章让你理清 【硬盘类型】 HDD、SSD、SSHD 和 【硬盘接口类型】 ATA、IDE、SATA、SCSI、SAS
  9. tomcat下servlet环境变量配置(转载)
  10. Edexcel A-Level化学真题讲解(1)