hdoj 5765 Bonds

来源:互联网 发布:淘宝打开店铺自动收藏 编辑:程序博客网 时间:2024/05/17 05:12

  设An个点的非空真子集,U为全集。枚举无序对(A,UA),如果AUA内的点都连通(关于连通性的判定,需要使用比较快的bfs方法),那么连接这两个集合的边是图的一个割。首先统计所有割的总数tot,然后对于每个(A,UA)对应的割,A内部的边和UA内部的边显然不在割中,dp计算每条边不在多少个割中即可,tot减去它就是答案。

#include <bits/stdc++.h>using namespace std;int n,m;int uu[410];int vv[410];int edges[1<<20];inline int lowbit(int x){    return x&(-x);}int adj[22];bool bfs(int mask){    int conn = lowbit(mask);    int T = n;    while(T--){        for(int i=0;i<n;i++){            if(((1<<i)&mask) && ((1<<i)&conn)){                conn |= adj[i];            }        }        if((conn&mask) == mask){            return 1;        }    }    return 0;}int main(){    int t;    cin>>t;    int cas = 0;    while(t--){        cas++;        memset(edges,0,sizeof(edges));        memset(adj,0,sizeof(adj));        cin>>n>>m;        for(int i=0;i<m;i++){            int u,v;            scanf("%d%d",&u,&v);            uu[i] = u;            vv[i] = v;            adj[u] |= (1<<v);            adj[v] |= (1<<u);        }        int End = 1<<n;        int tot = 0;        for(int k=1;k<End-1;k++){            if(k>(k^(End-1))){                continue;            }            if(bfs(k) && bfs(k^(End-1))){                edges[k] = 1;                edges[k^(End-1)] = 1;                tot++;            }        }        for(int i=0;i<n;i++){            for(int j=1;j<End;j++){                if((1<<i)&j){                    edges[(1<<i)^j] += edges[j];                }            }        }        printf("Case #%d:",cas);        for(int i=0;i<m;i++){            printf(" %d",tot - edges[(1<<uu[i])|(1<<vv[i])]);        }        printf("\n");    }     return 0;} 
0 0
原创粉丝点击