Hdu 5765 Bonds

本文介绍了一种使用位运算和广度优先搜索(BFS)来检查特定掩码下节点连通性的算法实现。该算法首先初始化已访问节点集合,并通过不断扩展待访问节点集合直至所有可达节点都被标记为已访问,以此判断输入掩码所代表的图是否完全连通。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接


check(mask) 就是用 bfs 的方式来检查 mask 是否联通

具体的, done 是已经访问过的点集, did 是可以访问的点集

首先找一个 mask 的点 start 加到 did

显然 done did 的子集,每一次找到一个在 did 中并且不在 done 中的点 st ,把和st直接联通的在 mask 中的点加到 did 里面,把 st 加到 done 里面,最后的 done 就是和 start 联通的点集了


位运算大法好~

#include<bits/stdc++.h>
using namespace std;

const int bit = 22;
const int maxn = 1<<bit;

int l[bit*bit],r[bit*bit];
int edge[bit];
int rev[maxn];

int cnt[maxn];
int lowbit(int x){
    return x & (-x);
}

bool check(int S){
    int done = 0;
    int did = lowbit(S);
    while(did != done){
        int st = rev[lowbit(did ^ done)];
        done |= 1<<st;
        did |= edge[st] & S;
    }
    return done == S;
}

int main(){
    int T;
    scanf("%d",&T);
    int n,m;
    int icase = 1;
    memset(rev,-1,sizeof(rev));
    for(int i=0;i<bit;i++) rev[1<<i] = i;
    while(T-- && ~scanf("%d %d",&n,&m)){
        memset(edge,0,sizeof(edge));
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<m;i++){
            scanf("%d %d",&l[i],&r[i]);
            edge[l[i]] |= 1<<r[i];
            edge[r[i]] |= 1<<l[i];
        }
        int bnd = (1<<n) - 1;
        int all = 0;
        for(int i=1;i<bnd;i++){
            if((i&1) && check(i) && check(bnd ^ i)){
                cnt[i]++,cnt[bnd^i]++;
                all++;
            }
        }
        for(int i=1;i<=bnd;i<<=1){
            for(int j=0;j<=bnd;j++){
                if(i&j)
                    cnt[i^j] += cnt[j];
            }
        }
        printf("Case #%d:",icase++);
        for(int i=0;i<m;i++){
            printf(" %d",all - cnt[(1<<l[i])|(1<<r[i])]);
        }
        puts("");
    }
    return 0;
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值