bzoj4668
并查集+最小生成树
首先我们发现这题可以lct维护最小生成树,但是发现如果生成树在之后是不会修改的,那么就想到了并查集,然后就不知道怎么做了。。。
其实当我们连接两个连通块的时候,两个连通块只能通过这一条边联通,所以这条边的两个端点是谁并不重要,因为两个连通块之间的通道最小值不会受到位置的影响。那么我们就可以利用并查集进行按秩合并,使树高只有logn,然后每次查询就是暴力lca查找路径最值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int n, m, ans; int fa[500010], d[500010]; int find(int x) { if(x == fa[x]) return x; int a = find(fa[x]); d[a] = min(d[a], d[x]); return fa[x] = a; } void connect(int u, int v) { int a = find(u), b = find(v); if(a == b) return; d[a] = min(d[a], d[b]); fa[b] = a; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) fa[i] = i; for(int i = 1; i <= m; ++i) { int opt, u, v; scanf("%d%d%d", &opt, &u, &v); u ^= ans; v ^= ans; if(opt == 0) connect(u, v); if(opt == 1) { int a = find(u), b = find(v); if(a != b) { ans = 0; puts("0"); } else printf("%d\n", ans = d[a]); } } return 0; }