// 并查集:路径压缩 + 按大小合并 structDSU { /* ======================================== */ int fa[maxn], siz[maxn]; voidinit( int N ){ for( int i = 1; i <= N; ++ i ) fa[i] = i, siz[i] = 1; } intfind( int x ){ return fa[x] == x ? x : fa[x] = find( fa[x] ); } boolmerge( int x, int y ){ int rx = find( x ), ry = find( y ); if( rx == ry ) return0; if( siz[rx] > siz[ry] ) swap( rx, ry ); fa[rx] = ry, siz[ry] += siz[rx]; return1; } boolsame( int x, int y ){ returnfind( x ) == find( y ); } intsize( int x ){ return siz[find( x )]; } /* ======================================== */ } dsu;
disc.clear( ); for( int i = 1; i <= n; ++ i ) { cin >> a[i].i >> a[i].j >> a[i].c; disc.add( a[i].i ); disc.add( a[i].j ); } disc.init( ); dsu.init( disc.size( ) );
for( int i = 1; i <= n; ++ i ) { auto [x, y, c] = a[i]; int dx = disc.get_idx( x ), dy = disc.get_idx( y ); if( c == 1 ) dsu.merge( dx, dy ); }
for( int i = 1; i <= n; ++ i ) { auto [x, y, c] = a[i]; int dx = disc.get_idx( x ), dy = disc.get_idx( y ); if( c == 0 ) if( dsu.same( dx, dy ) ) ok = 0; }
boolcheck( double r, int n, int m ){ int L = 0, R = m + 1; dsu.init( m + 1 ); for( int i = 1; i <= m; ++ i ) { if( ps[i].x <= r ) dsu.merge( i, L ); if( n - ps[i].x <= r ) dsu.merge( i, R ); } for( int i = 1; i <= m; ++ i ) { for( int j = i + 1; j <= m; ++ j ) { double dx = ps[i].x - ps[j].x, dy = ps[i].y - ps[j].y; if( dx * dx + dy * dy <= 4.0 * r * r ) dsu.merge( i, j ); } } return dsu.same( L, R ); }
voidsolve( ){ ll n = read( ), m = read( ); for( int i = 1; i <= m; ++ i ) ps[i].x = read( ), ps[i].y = read( ); double l = 0, r = 200000; for( int t = 1; t <= 100; ++ t ) { double mid = ( l + r ) / 2.0; if( check( mid, n, m ) ) r = mid; else l = mid; } cout << fixed << setprecision( 2 ) << r << '\n'; }
vector<int> adj[maxn]; bool broken[maxn]; // break; int ans[maxn]; int ks[maxn];
voidsolve( ){ int n = read( ), m = read( ); dsu.init( n );
for( int i = 1; i <= m; ++ i ) { int u = read( ) + 1, v = read( ) + 1; adj[u].push_back( v ); adj[v].push_back( u ); }
int k = read( ); for( int i = 1; i <= k; ++ i ) { ks[i] = read( ) + 1; broken[ks[i]] = true; }
int cnt = n - k; // 连通块数量 for( int u = 1; u <= n; ++ u ) { if( broken[u] ) continue; for( int v : adj[u] ) { if( broken[v] ) continue; if( dsu.merge( u, v ) ) cnt --; } }
ans[k + 1] = cnt; for( int i = k; i >= 1; -- i ) { int u = ks[i]; broken[u] = 0; cnt ++; for( int v : adj[u] ) { if( broken[v] ) continue; if( dsu.merge( u, v ) ) cnt --; // 尝试恢复 u 的相邻边 } ans[i] = cnt; // 恢复 u 后的连通块数量 }
for( int i = 1; i <= k + 1; ++ i ) { cout << ans[i] << '\n'; } }
// 二倍域并查集:维护同类 / 异类 structExtDSU { /* ======================================== */ int fa[maxn << 1], siz[maxn << 1], sz; voidinit( int N ){ sz = N; for( int i = 1; i <= (N << 1); ++ i ) fa[i] = i, siz[i] = 1; } intrev( int x ){ return x <= sz ? x + sz : x - sz; } intfind( int x ){ return fa[x] == x ? x : fa[x] = find( fa[x] ); } boolmerge( int x, int y ){ int rx = find( x ), ry = find( y ); if( rx == ry ) return0; if( siz[rx] > siz[ry] ) swap( rx, ry ); fa[rx] = ry, siz[ry] += siz[rx]; return1; } boolsame( int x, int y ){ returnfind( x ) == find( y ); } intsize( int x ){ return siz[find( x )]; } boolsetSame( int x, int y ){ if( same( x, rev( y ) ) ) return0; merge( x, y ), merge( rev( x ), rev( y ) ); return1; } boolsetDiff( int x, int y ){ if( same( x, y ) ) return0; merge( x, rev( y ) ), merge( rev( x ), y ); return1; } /* ======================================== */ } dsu;
structPerson { int a, b, c; booloperator < ( const Person &oth ) const { return c > oth.c; } } p[maxm];
voidsolve( ){ int n = read( ), m = read( ); for( int i = 1; i <= m; ++ i ) { p[i].a = read( ), p[i].b = read( ), p[i].c = read( ); } sort( p + 1, p + m + 1 );
dsu.init( n ); for( int i = 1; i <= m; ++ i ) { auto [ai, bi, ci] = p[i]; if( !dsu.setDiff( ai, bi ) ) { cout << ci << '\n'; return; } } cout << 0 << '\n'; }
voidsolve( ){ int n = read( ), k = read( ); dsu.init( n );
int ans = 0; for( int i = 1; i <= k; ++ i ) { int opt = read( ), x = read( ), y = read( ); if( x > n || y > n ) ans ++; elseif( opt == 1 && !dsu.setSame( x, y ) ) ans ++; elseif( opt == 2 && !dsu.setEat( x, y ) ) ans ++; } cout << ans << '\n'; }
// 带权并查集:维护 (val[x] - val[y]) mod mod structWDSU { /* ======================================== */ staticconstint mod = 3; int fa[maxn], siz[maxn], dis[maxn]; // dis[x] = val[x] - val[fa[x]] (mod mod) intnorm( int x ){ return ( x %= mod ) < 0 ? x + mod : x; } voidinit( int N ){ for( int i = 1; i <= N; ++ i ) fa[i] = i, siz[i] = 1, dis[i] = 0; } intfind( int x ){ if( fa[x] == x ) return x; int f = fa[x]; fa[x] = find( f ); dis[x] = norm( dis[x] + dis[f] ); return fa[x]; } // 查询 (val[x] - val[y]) mod mod,调用前最好保证 same(x, y) intdist( int x, int y ){ find( x ), find( y ); returnnorm( dis[x] - dis[y] ); } // 加入关系 val[x] - val[y] = w (mod mod),返回 false 表示矛盾 boolmerge( int x, int y, int w ){ w = norm( w ); int rx = find( x ), ry = find( y ); if( rx == ry ) returndist( x, y ) == w; if( siz[rx] > siz[ry] ) { fa[ry] = rx; dis[ry] = norm( -w + dis[x] - dis[y] ); siz[rx] += siz[ry]; } else { fa[rx] = ry; dis[rx] = norm( w - dis[x] + dis[y] ); siz[ry] += siz[rx]; } return1; } boolsame( int x, int y ){ returnfind( x ) == find( y ); } intsize( int x ){ return siz[find( x )]; } /* ======================================== */ } dsu;
voidsolve( ){ int n = read( ), k = read( ); dsu.init( n ); int ans = 0; for( int i = 1; i <= k; ++ i ) { int opt = read( ), x = read( ), y = read( ); if( x > n || y > n ) ans ++; elseif( opt == 1 ) { if( dsu.same( x, y ) && dsu.dist( x, y ) != 0 ) ans ++; else dsu.merge( x, y, 0 ); } elseif( opt == 2 ) { if( dsu.same( x, y ) && dsu.dist( x, y ) != 1 ) ans ++; else dsu.merge( x, y, 1 ); } } cout << ans << '\n'; }
#include<bits/stdc++.h> usingnamespace std; using ll = longlong;
constint maxn = 2e5 + 5;
// 队列合并并查集:整列接到整列后面,维护到队头距离 structQDSU { /* ======================================== */ int fa[maxn], siz[maxn]; ll dis[maxn]; // dis[x] = x 到所在列队头的距离 voidinit( int N ){ for( int i = 1; i <= N; ++ i ) fa[i] = i, siz[i] = 1, dis[i] = 0; } intfind( int x ){ if( fa[x] == x ) return x; int f = fa[x]; fa[x] = find( fa[x] ); dis[x] += dis[f]; return fa[x]; } // 把 x 所在整列接到 y 所在整列后面 voidmove( int x, int y ){ int rx = find( x ), ry = find( y ); if( rx == ry ) return; fa[rx] = ry; dis[rx] = siz[ry]; siz[ry] += siz[rx]; } boolsame( int x, int y ){ returnfind( x ) == find( y ); } intsize( int x ){ return siz[find( x )]; } // x 到队头的距离 ll pos( int x ){ find( x ); return dis[x]; } // x, y 之间隔了几个元素;调用前需保证 same(x, y) ll dist( int x, int y ){ find( x ), find( y ); returnabs( dis[x] - dis[y] ) - 1; } /* ======================================== */ } dsu;