[codeforces] Gym
来源:互联网 发布:软件行业税收优惠政策 编辑:程序博客网 时间:2024/05/17 08:55
[codeforces] Gym - 100814C Connecting Graph (并查集+LCA)
题目链接:100814C Connecting Graph
题目大意:
给定n个点, m个操作, 操作由两种形式
数据范围:
解题思路:
两个点什么时候最早连通就是这两个点之间的最大值, 可以想到用LCA+倍增维护最大值。 题中并没有说肯定是棵树, 但是如果两个点之前已经联通了, 当前这条边就没有必要加进去了(有点最小生成树的感觉), 所以最后肯定生成的是一个树。
这道题的主要思想就是用LCA + 倍增维护最大值。
代码:
/********************************************** *Author* :ZZZZone *reated Time* : 2017/8/8 20:57:14 *ended Time* : 2017/8/9 12:05:21*********************************************/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef pair<int, int> PII;typedef long long LL;typedef unsigned long long ULL;const int MaxN = 1e5;int fa[MaxN + 5], dis[MaxN + 5];int up[MaxN + 5][25], Max[MaxN + 5][25];vector<PII>edge[MaxN + 5];struct NODE{ int p, u, v;}q[MaxN + 5];int T, n, m, tot;void init(){ for(int i = 1; i<= n; i++) fa[i] = i; memset(dis, 0, sizeof(dis)); memset(up, 0, sizeof(up)); memset(Max, 0, sizeof(Max)); memset(edge, 0, sizeof(edge)); tot = 0;}int find(int x){ if(fa[x] == x) return x; else return fa[x] = find(fa[x]);}void Union(int u, int v){ int fu = find(u), fv = find(v); if(fu != fv) fa[fu] = fv;}void dfs(int u){ /* for(int i = 1; i <= 20; i++){ up[u][i] = up[up[u][i - 1]][i - 1]; Max[u][i] = max(Max[u][i - 1], Max[up[u][i - 1]][i - 1]); } */ for(int i = 0; i < edge[u].size(); i++){ int v = edge[u][i].first; int len = edge[u][i].second; if(dis[v] == 0){ dis[v] = dis[u] + 1; Max[v][0] = len; up[v][0] = u; dfs(v); } }}void init_lca(){ for(int j = 1; (1 << j) <= n; j++){ for(int i = 1; i <= n; i++){ up[i][j] = up[up[i][j - 1]][j - 1]; Max[i][j] = max(Max[i][j - 1], Max[up[i][j - 1]][j - 1]); } }}int getans(int a, int b){ if(dis[a] < dis[b]) swap(a, b); int c = dis[a] - dis[b], res = 0; for(int i = 0; (1 << i) <= n; i++){ if(c & (1 << i)){ res = max(res, Max[a][i]); a = up[a][i]; } } if(a == b) return res; for(int i = 20; i >= 0; i--){ if(up[a][i] != up[b][i]){ res = max(res, Max[a][i]); res = max(res, Max[b][i]); a = up[a][i]; b = up[b][i]; } } return max(res, max(Max[a][0], Max[b][0]));}int main(){ scanf("%d", &T); while(T--){ scanf("%d %d", &n, &m); init(); for(int i = 1; i <= m; i++){ int x, u, v; scanf("%d %d %d", &x, &u, &v); if(x == 1){ int fu = find(u), fv = find(v); if(fu == fv) continue; fa[fu] = fv; edge[u].push_back(make_pair(v, i)); edge[v].push_back(make_pair(u, i)); } else q[++tot].p = i, q[tot].u = u, q[tot].v = v; } for(int i = 1; i <= n; i++) if(dis[i] == 0){ dis[i] = 1; dfs(i); } init_lca(); for(int i = 1; i<= tot; i++){ int fu = find(q[i].u), fv = find(q[i].v); if(fu != fv) printf("-1\n"); else { int ans = getans(q[i].u, q[i].v); if(ans > q[i].p) printf("-1\n"); else printf("%d\n", ans); } } } return 0;}
在此输入正文
阅读全文
0 0
- 【Codeforces Gym
- 【codeforces Gym
- codeforces Gym
- codeforces Gym
- codeforces Gym
- codeforces Gym
- Codeforces Gym
- Codeforces Gym
- Codeforces Gym
- codeforces Gym
- Codeforces Gym
- Codeforces Gym
- Codeforces Gym
- [codeforces] Gym
- [codeforces] Gym
- [codeforces] Gym
- [codeforces] Gym
- [codeforces] Gym
- centos 6.5下mysql的安装图解
- 数据库之触发器
- JavaScript创建、添加、删除元素
- sed和awk之sed篇(含sed高级用法)
- Java:操作字符串的StringBuffer类用法
- [codeforces] Gym
- HDFS内副本和块的状态分析
- ProxyStrike运行bug解决办法
- No appenders could be found for logger
- Android程序永不被系统kill
- 动态代理
- K-means优化
- JS的各种宽高的含义。
- verilog中的integer和reg的差别