Gym 100814C Connecting Graph 并查集+LCA
Description
Statements
Alex is known to be very clever, but Walter does not believe that. In order to test Alex, he invented a new game. He gave Alex nnodes, and a list of queries. Walter then gives Alex one query every second, there are two types of queries:
means: adding an undirected edge between nodes u and v.
means: what was the earliest time (query index) when u and v became connected? 2 nodes are connected if there is a path of edges between them. Alex can solve this problem easily, but he is too busy now, so he is asking for your help.
Input
The first line contains an integer T, the number of test cases. Each test case begins with a line containing two integers (1 ≤ n, m ≤ 105), the number of nodes and queries, respectively. Then there are m lines, each line represents a query and contains three integers,type, u and v ( , 1 ≤ u, v ≤ n)
Output
For each query of type 2, print one line with one integer, the answer to the query. If the 2 nodes in the query are not connected, print -1.
Sample Input
1
4 5
1 1 2
2 1 2
1 2 3
2 1 3
2 1 4
1
3
-1
Hint
Warning: large Input/Output data, be careful with certain languages.
2016寒假训练04C,赛后补的:题意是给出m中操作,分别是1, u, v,既节点u,v之间连一条边,2, u, v即询问是最早是第几次操作使得u,v联通
可以用并查集维护连通性,如果(u, v)已经联通,那么对于操作1,(u,v)就不再连边,这样对于每一个联通块得到的是一颗树,所有的联通块对应于森林
维护mx[u][i]表示节点u到其第2^i个祖先之间边权的最大值,这样在查询lca的时候就能得到u, v之间路径的最大边权,就是对应于2的答案
#include <bits/stdc++.h>
using namespace std;
const int N = ;
const int DEG = ;
typedef pair<int, int> pii;
int head[N], tot;
struct Edge {
int v, w, next;
Edge() {}
Edge(int v, int w, int next) : v(v), w(w), next(next) {}
}e[N << ];
struct Query {
int u, v, w;
Query() {}
Query(int u, int v, int w) : u(u), v(v), w(w) {}
}q[N];
int f[N][DEG + ], mx[N][DEG + ], fa[N], deg[N];
void init(int n) {
for(int i = ; i <= n; ++i) fa[i] = i;
memset(head, -, sizeof head);
tot = ;
}
void add(int u, int v, int w) {
e[tot] = Edge(v, w, head[u]);
head[u] = tot++;
}
int find(int x) {
return fa[x] == x ?
x : fa[x] = find(fa[x]);
}
void BFS(int rt) {
queue<int> que;
deg[rt] = ;
f[rt][] = rt;
mx[rt][] = ;
que.push(rt);
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = ; i < DEG; ++i) {
f[u][i] = f[f[u][i - ]][i - ];
mx[u][i] = max(mx[u][i - ], mx[f[u][i-]][i-]);
}
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
int w = e[i].w;
if(v == f[u][]) continue;
deg[v] = deg[u] + ;
f[v][] = u;
mx[v][] = w;
que.push(v);
}
}
}
int getmx(int u, int v) {
if(deg[u] > deg[v]) swap(u, v);
int hu = deg[u], hv = deg[v];
int tu = u, tv = v, res = ;
for(int det = hv - hu, i = ; det; det >>= , ++i) {
if(det & ) { res = max(res, mx[tv][i]); tv = f[tv][i]; }
}
if(tu == tv) return res;
for(int i = DEG - ; i >= ; --i)
{
if(f[tu][i] == f[tv][i]) continue;
res = max(res, mx[tu][i]);
res = max(res, mx[tv][i]);
tu = f[tu][i];
tv = f[tv][i];
}
return max(res, max(mx[tu][], mx[tv][]));
}
int main() {
int _; scanf("%d", &_);
while(_ --)
{
int n, m;
scanf("%d%d", &n, &m);
int u, v, t, num = , res;
init(n);
for(int i = ; i <= m; ++i) {
scanf("%d%d%d", &t, &u, &v);
if(t == ) {
int fu = find(u);
int fv = find(v);
if(fu == fv) continue;
fa[fu] = fv;
add(u, v, i);
add(v, u, i);
}else {
q[num++] = Query(u, v, i);
}
}
for(int i = ; i <= n; ++i) if(fa[i] == i) {
BFS(i);
} for(int i = ; i < num; ++i) {
if(q[i].u == q[i].v) puts("");
else {
int fu = find(q[i].u);
int fv = find(q[i].v);
if(fu != fv) puts("-1");
else {
res = getmx(q[i].u, q[i].v);
printf("%d\n", res > q[i].w ? - : res);
}
}
}
}
}
Gym 100814C Connecting Graph 并查集+LCA的更多相关文章
- Codeforces Gym 100814C Connecting Graph 树剖并查集/LCA并查集
初始的时候有一个只有n个点的图(n <= 1e5), 现在进行m( m <= 1e5 )次操作 每次操作要么添加一条无向边, 要么询问之前结点u和v最早在哪一次操作的时候连通了 /* * ...
- hdu 2874 Connections between cities (并查集+LCA)
Connections between cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- hdu6074[并查集+LCA+思维] 2017多校4
看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...
- Network-POJ3694并查集+LCA
Network Time Limit: 5000MS Memory Limit: 65536K Description A network administrator manages ...
- Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph 并查集
D. Mr. Kitayuta's Colorful Graph Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/ ...
- HDU6074 Phone Call (并查集 LCA)
Phone Call Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Tota ...
- [并查集+LCA USACO18OPEN ] Disruption
https://www.luogu.org/problemnew/show/P4374 一看这道题就是一个妙题,然后题解什么树链剖分...珂朵莉树... 还不如并查集来的实在!我们知道并查集本来就是路 ...
- Mobile Phone Network CodeForces - 1023F(并查集lca+修改环)
题意: 就是有几个点,你掌控了几条路,你的商业对手也掌控了几条路,然后你想让游客都把你的所有路都走完,那么你就有钱了,但你又想挣的钱最多,真是的过分..哈哈 游客肯定要对比一下你的对手的路 看看那个便 ...
- Codeforces 336D Dima and Trap Graph 并查集
Dima and Trap Graph 枚举区间的左端点, 然后那些左端点比枚举的左端点小的都按右端点排序然后并查集去check #include<bits/stdc++.h> #defi ...
随机推荐
- odoo注销后在登录时的用户名和密码
初识odoo时会遇到注销后无法登陆的情况,一般原因是没有留意管理员邮件地址和对应的密码所致.初始情况下默认的邮件地址为admin,密码为数据库创建时提供的密码.
- php正则表达式、数组
<?php $s = "he8llo5wor6ld"; $s = preg_replace("/\d/","#",$s);按照正则表达 ...
- Tmux的安装、使用与配置
tmux 安装.使用.配置 因上线需求,故需要使用tumx,方便上线 tmux功能 提供了强大的.易于使用的命令行界面 可横向.纵向分割窗口 窗格可以自由移动和调整大小,或者直接利用四个预设布局之一 ...
- Mac下java开发环境的搭建与开发工具的安装
一.安装JDK 1.根据你当前环境的需要,下载相应的JDK并安装,安装步骤与其他Mac软件安装方法相同,我安装的是jdk1.8.0_74.jdk,mac中jdk1.8的默认位置:/Library/Ja ...
- Linux定时任务设定
使用crontab 命令进行设定. 详情可参见:http://blog.csdn.net/xiyuan1999/article/details/8160977. 共有6项构成,前5项为时间:分 时 天 ...
- 数据存储-CoreData总结
CoreData /*英译 Entity:实体 Attributes:属性 binary:二进制 persistent:持续化 coordinator:协调者 meging:合并 configura ...
- Mac平台下Opencv开发环境搭建
OpenCV(Open Source Computer Vision Library),是一个开源的跨平台的计算机视觉库,它实现了图像处理和计算机视觉领域的很多通用算法,可以在多种计算机平台上运行,支 ...
- 第一个JAVA创建
1.file-new-java project 创建项目文件夹 2.在项目文件夹new-class 3.java对大小写比较敏感 输入代码 public class HELLOWORD { publ ...
- Javascript和Java获取各种form表单信息的简单实例
大家都知道我们在提交form的时候用了多种input表单.可是不是每一种input表单都是很简单的用Document.getElementById的方式就可以获取到的.有一些组合的form类似于che ...
- MyEclipse破解(MEGen.java)
步骤: 1.将MEGen.java粘贴到任意web项目下,运行结果如下: 2.输入注册名:如sun,得到注册码: 3.Window >> Preference >> S ...