Description

standard input/output 
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,typeu 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

Input
1
4 5
1 1 2
2 1 2
1 2 3
2 1 3
2 1 4
Output
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的更多相关文章

  1. Codeforces Gym 100814C Connecting Graph 树剖并查集/LCA并查集

    初始的时候有一个只有n个点的图(n <= 1e5), 现在进行m( m <= 1e5 )次操作 每次操作要么添加一条无向边, 要么询问之前结点u和v最早在哪一次操作的时候连通了 /* * ...

  2. hdu 2874 Connections between cities (并查集+LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  3. hdu6074[并查集+LCA+思维] 2017多校4

    看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...

  4. Network-POJ3694并查集+LCA

    Network Time Limit: 5000MS   Memory Limit: 65536K       Description A network administrator manages ...

  5. 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/ ...

  6. HDU6074 Phone Call (并查集 LCA)

    Phone Call Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Tota ...

  7. [并查集+LCA USACO18OPEN ] Disruption

    https://www.luogu.org/problemnew/show/P4374 一看这道题就是一个妙题,然后题解什么树链剖分...珂朵莉树... 还不如并查集来的实在!我们知道并查集本来就是路 ...

  8. Mobile Phone Network CodeForces - 1023F(并查集lca+修改环)

    题意: 就是有几个点,你掌控了几条路,你的商业对手也掌控了几条路,然后你想让游客都把你的所有路都走完,那么你就有钱了,但你又想挣的钱最多,真是的过分..哈哈 游客肯定要对比一下你的对手的路 看看那个便 ...

  9. Codeforces 336D Dima and Trap Graph 并查集

    Dima and Trap Graph 枚举区间的左端点, 然后那些左端点比枚举的左端点小的都按右端点排序然后并查集去check #include<bits/stdc++.h> #defi ...

随机推荐

  1. 【leetcode】Shortest Palindrome(hard)★

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  2. POJ 1222 EXTENDED LIGHTS OUT (高斯消元)

    题目链接 题意:5*6矩阵中有30个灯,操作一个灯,周围的上下左右四个灯会发生相应变化 即由灭变亮,由亮变灭,如何操作使灯全灭? 题解:这个问题是很经典的高斯消元问题.同一个按钮最多只能被按一次,因为 ...

  3. Quartz结合SPRING多任务定时调用

    定义两个被调度的类 public class QuartzJob { public void work() { System.out.println(Spring Quartz的任务调度1被调用!&q ...

  4. Quatre 2D的绘图功能的三个步骤(上下文,绘图,渲染)

    一.qurza2d是怎么将绘图信息和绘图的属性绘制到图形上下文中去的? 说明: 新建一个项目,自定义一个view类和storyboard关联后,重写该类中的drowrect方法. 画线的三个步骤: ( ...

  5. 学习JNDI

    既然datasource对象有tomcat提供,那么我们如何在应用程序中获得它呢,tomcat把这个对象放在JNDI服务中, 并用一个名字把它关联起来,我们在应用程序中,只需通过JNDI搜索这个名字, ...

  6. 三、jQuery--jQuery基础--jQuery基础课程--第7章 jQuery 动画特效

    1.调用show()和hide()方法显示和隐藏元素 show()和hide()方法用于显示或隐藏页面中的元素,它的调用格式分别为:$(selector).hide(speed,[callback]) ...

  7. Powershell实例小结(服务管理)

    有关服务管理的具体实例脚本如下: #$lists="1.1.1.1","2.2.2.2" #远程ip列表 foreach ($list in $lists){ ...

  8. CLR via C#(01)-.NET平台下代码是怎么跑起来的

    1. 源代码编译为托管模块 程序在.NET框架下运行,首先要将源代码编译为托管模块.CLR是一个可以被多种语言所使用的运行时,它的很多特性可以用于所有面向它的开发语言.微软开发了多种语言的编译器,编译 ...

  9. 数据结构和算法 – 7.散列和 Hashtable 类

    7.1.散列函数 散列是一种常见的存储数据的技术,按照这种方式可以非常迅速地插入和取回数据.散列所采用的数据结构被称为是散列表.尽管散列表提供了快速地插入.删除.以及取回数据的操作,但是诸如查找最大值 ...

  10. jQuery – 6.选择器

    1. 属性过滤选择器: 1. $("div[id]")选取有id属性的<div> 2. $("div[title=test]")选取title属性为 ...