Hdu 5765 Bonds

丢链接


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

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

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

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


位运算大法好~

#include
using namespace std;

const int bit = 22;
const int maxn = 1<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<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;i1<while(T-- && ~scanf("%d %d",&n,&m)){
        memset(edge,0,sizeof(edge));
        memset(cnt,0,sizeof(cnt));
        for(int i=0;iscanf("%d %d",&l[i],&r[i]);
            edge[l[i]] |= 1<1<int bnd = (1<1;
        int all = 0;
        for(int i=1;iif((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;iprintf(" %d",all - cnt[(1<1<puts("");
    }
    return 0;

你可能感兴趣的:(--图论---)