周赛-薇尔莉特的委托-并查集应用

题目链接
思路:
分别对所有路建立前缀并查集和后缀并查集,破坏L到R的路时,只需合并L-1,和R+1的集合。
Code:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 1e3+66;
const int MAXN = 1e4+6;
int n , m ;
struct Node{
    int u , v ;
    int pre[AX];
    void init(){
        for( int i = 0 ; i <= 1000 ; i++ ){
            pre[i] = i ;
        }
    }
    int find( int x ){
        return x == pre[x] ? pre[x] : pre[x] = find(pre[x]) ;
    }
    void mix( int x , int y ){
        int xx = find(x);
        int yy = find(y);
        if( xx != yy ) pre[xx] = yy ;
    }
}l[MAXN] , r[MAXN] , a[MAXN];
int vis[AX];
void solve( Node l , Node r ){
    for( int i = 1 ;  i <= n ; i++ ){
        l.mix( i , r.find(i) );
    }
    int res = -1;
    memset( vis , 0 , sizeof(vis) );
    for( int i = 1 ; i <= n ; i++ ){
        int x = l.find(i);
        vis[x] ++ ;
        res = max( res , vis[x] );
    }
    printf("%d\n",res);
}

int main(){
    scanf("%d%d",&n,&m);
    for( int i = 1 ; i <= m ; i++ ){
        scanf("%d%d",&a[i].u,&a[i].v);
    }
    l[0].init();
    r[m+1].init();  
    for( int i = 1 ; i <= m ; i++ ){
        l[i] = l[i-1];
        l[i].mix( a[i].u , a[i].v );
    }
    for( int i = m ; i >= 1 ; i-- ){
        r[i] = r[i+1];
        r[i].mix( a[i].u , a[i].v );
    }
    int d ;
    scanf("%d",&d);
    int x , y ; 
    for( int i = 0 ; i < d ; i++ ){
        scanf("%d%d",&x,&y);
        solve( l[x-1] , r[y+1] );
    }
    return 0 ; 
}

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/81297188