(涛菜菜)并查集

目录

模板

题目

1.畅通工程

 2.帮派

模板

1.初始化

void init(){//初始化集合号
    for(int i=1;i<=n;i++)
         fa[i]=i;  //把节点i的集合号初始化为自身
}

2.查找

int Find(int x){  //查找
    if(x!=fa[x])
        fa[x]=Find(fa[x]);
    return fa[x];
}

3.合并

void Union(iont x,int y){   //合并
     int a=Find(x);
     int b=Find(y);
     if(a!=b)
          fa[b]=a;
}

题目

1.畅通工程

for(int i=1;i<=n;i++)
    fa[i]=i;   //初始化集合号为自身‘
for(int i=0;i<m;i++){
    scanf("%d%d",&x,&y);
    Union(x,y);
}
for(int i=1;i<=n;i++){
    if(i==fa[i])
        ans++;
}
printf("%d",ans-1);//记得减1
 2.帮派

思路 

划分为不同集合的方法:可以给每一个节点x都复制一个影子x+n,将x,y划分为不同的集合,只需将x和y的影子合并为一个集合,并将x+n和y合并为一个集合

//初始化
void init(){
    for(int i=1;i<=2*n;i++){
        fa[i]=i;
        h[i]=0;
    }
}
//查找集合号
int Find(int x){
    if(x!=fa[x])
        fa[x]=Find(fa[x]);
    return fa[x];
}
//合并
void Union(int x,int y){
    int a=Find(x);
    int b=Find(y);
    if(a==b)
        return;
    if(h[a]>h[b])   //启发式合并,把矮树合并到高树之下
        fa[b]=a;
    else{
        fa[a]=b;
        if(h[a]==h[b])
            h[b]++;
    }
}
//判定结果
while(m--){
    char ch[2];
    int x,y;
    scanf("%s%d%d",ch,&x,&y);
    if(ch[0]=='D'){
        Union(x,y+n);
        Union(x+n,y);
    }
    else{
        if(Find(y+n)==Find(x)||Find(x+n)==Find(y))
             printf("in different gangs");
        else if(Find(y)==Find(x)||Find(x+n)==Find(y+n))
            printf("in the same gang");
        else
            printf("not sure");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值