题意:

nnn个点,mmm个操作,操作共两类。①1uv①\ 1\ u\ v① 1 u v 表示在图中加一条边连接u、vu、vu、v,②2uv②\ 2\ u\ v② 2 u v 表示查询 uuu 与 vvv 最早是在哪一次加边操作后连通,不连通输−1-1−1。 (1≤n,m≤105)(1\leq n,m\leq 10^5)(1≤n,m≤105)


思路:

维护连通性,最直观的想法就是用并查集来维护连通性。但是如何通过并查集来查看两点最早什么时候连通呢?

首先可以知道并查集维护的其实是一个森林,假如我们不破坏树的结构,即不进行路径压缩,则并查集每次加边,则将边权定义为操作编号,那么两点树上边权最大值就是两点最早连通的加边操作。

因此问题变成如何维护树的结构进行并查集合并,方法就是按秩合并,将小的树合并到大的树上,这样可以保证每个节点最多被合并 log(n)log(n)log(n) 次,因此每个节点的高度最多为log(n)log(n)log(n)。因此对于每次查询,我们可以将两个点到根节点的路径直接取出,然后查询第一次遇到的位置,输出达到这个位置之前的边权最大值即可。


总结:

路径压缩并查集:速度快,最后会变成每棵树只有两层的森林,常见拓展为带权并查集。

按秩合并并查集:将小树合并到大树上,最后每个节点的高度最多为lognlognlogn,可以维护树的结构,采取的是树上启发式合并的思想。也可以对树上边权赋值,维护比较关系。


代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;int f[N],n,m,siz[N],d[N],flag[N],vis[N];int find(int x){if(x == f[x]) return x;else return find(f[x]);
}int solve(int u,int v){vis[u] = 1; flag[u] = 0; int w = 0;while(f[u] != u){w = max(w,d[u]);vis[f[u]] = 1; flag[f[u]] = w;u = f[u];}vis[u] = 1, flag[u] = w;w = 0;if(vis[v] == 1) return flag[v];while(f[v] != v){w = max(w,d[v]);if(vis[f[v]] == 1) return max(w,flag[f[v]]);v = f[v];}if(vis[v] == 1) return max(flag[v],w);
}void clear(int u){while(f[u] != u) vis[u] = 0, flag[u] = 0, u = f[u];vis[u] = 0, flag[u] = 0;
}int main()
{int _; scanf("%d",&_);while(_--){scanf("%d%d",&n,&m);rep(i,0,n) f[i] = i, d[i] = 0, siz[i] = 1;rep(i,1,m){int op,u,v; scanf("%d%d%d",&op,&u,&v);int xu = find(u), xv = find(v);if(op == 1 && xu != xv){if(siz[xu] < siz[xv]) f[xu] = xv, d[xu] = i, siz[xv] += siz[xu];else f[xv] = xu, d[xv] = i, siz[xu] += siz[xv];}else if(op == 2){if(xu != xv) printf("-1\n");else{printf("%d\n",solve(u,v));clear(u);}}}}return 0;
}

【ACM International Collegiate Programming Contest Gym-100814 C】Connecting Graph【并查集按秩合并】相关推荐

  1. 2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 Apare_xzc

    2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 by xzc,zx,lj 先 ...

  2. 2015 ACM Arabella Collegiate Programming Contest(F题)

    F. Palindrome [ Color: Pink ] A string is palindrome if it can be read the same way in either direct ...

  3. Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest

    比赛链接: http://codeforces.com/gym/100676 题目链接: http://codeforces.com/gym/100676/attachments/download/3 ...

  4. Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest(二月十日训练赛)

    A(By talker): 题意分析:以a(int) op b(int)形式给出两个整数和操作符, 求两个整数是否存在操作符所给定的关系 ,有则输出true,无则输出false:思路:由于无时间复杂度 ...

  5. 2015 ACM Arabella Collegiate Programming Contest

    题目链接:https://vjudge.net/contest/154238#overview. ABCDE都是水题. F题,一开始分类讨论,结果似乎写挫了,WA了一发.果断换并查集上,A了. G题, ...

  6. gym100676 [小熊骑士限定]2015 ACM Arabella Collegiate Programming Contest

    Kuma Rider久违的第二场训练,这场很水,又在vj的榜单上看到第一场的大哥了,2小时ak,大哥牛啤! A.水 #include<cstdio> #include<iostrea ...

  7. GYM 2015 ACM Syrian Collegiate Programming Contest

    题目链接:http://codeforces.com/gym/101086 A My Friend of Misery B Brother Louie C Everything D Secure bu ...

  8. 2017 ACM Arabella Collegiate Programming Contest(solved 11/13)

    省选考前单挑做点ACM练练细节还是很不错的嘛- 福利:http://codeforces.com/gym/101350 先来放上惨不忍睹的virtual participate成绩(中间跑去食堂吃饭于 ...

  9. 2017 ACM Arabella Collegiate Programming Contest div2的题,部分题目写个题解

    F. Monkeying Around   维护点在多少个线段上 http://codeforces.com/gym/101350/problem/F 题意:有m个笑话,每个笑话的区间是[L, R], ...

  10. 脑洞 博弈 E. Competitive Seagulls 2017 ACM Arabella Collegiate Programming Contest

    题目链接:http://codeforces.com/gym/101350/problem/E 题目大意:给你一个长度为n的方格,方格上面都被染色成了白色.每次染色都是选择白色的,假设目前选择的这块白 ...

最新文章

  1. 24张图带你彻底理解Java中的21种锁
  2. The Maximum Unreachable Node Set
  3. hibenate.hbm2ddl.auto属性详解
  4. Linux的一些简单命令操作
  5. java开发环境以及数据类型
  6. 网上讨论“电商平台打败了实体店”?
  7. SQL2K数据库开发七之表操作添加删除和修改列
  8. java读xml文件一般用什么_java读xml文件
  9. 现代通信原理4.2:随机过程
  10. react-native 修改app应用名称
  11. Jeff Dean执笔:一文看尽2018谷歌AI重大成果
  12. 淘宝双11大数据分析(Spark 分析篇)
  13. 探寻机器人创客教育中的趣味
  14. Nosql初探(voldemort)
  15. 小而美的ToDo 待办事项便签工具,高效管理工作生活一切琐事
  16. EasyExcel实现下载Excel(解决无法从浏览器下载问题)
  17. Zephyr驱动程序框架简介
  18. day26-爬虫-scrapy框架初识
  19. 用python简单入门写糖葫芦!
  20. 抗量子加密:为什么迫切需要它

热门文章

  1. VC++ chap19 动态链接库 VC++ 孙鑫
  2. 如何让普通用户执行一些root用户才能执行的命令
  3. 写PHP还是Zend好用
  4. Linux inittab和oracle lsntctl 启动的问题解决办法
  5. 小偷写给失主的一封信 雷人啊!!
  6. 最短路径例题(Floyd、Dijkstra)
  7. python调用c++动态库_python调用c++开发的动态库
  8. unix编程实训教程之 more(觉醒篇一 Begin)
  9. 基于几何学习图像的三维重建发展_基于深度学习的三维重建——MVSNet系列论文解读...
  10. php mysql日期区间_php – 3个日期范围之间的Mysql查询