• HDU 4997 Biconnected (状态压缩DP)


    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4997

    题意:一个n个点的完全图中去掉一些边。求这个图有多少个子图是边双联通的。(就是去掉任意一条边之后仍是联通的)

    思路:

    const int mod=1000000007;
    const int N=11;
    
    int conn[1<<N],disc[1<<N],edge[1<<N];
    int bico[1<<N],unco[1<<N],meth[1<<N][1<<N];
    int n,m;
    int a[N][N];
    
    void cal(int st)
    {
        edge[st]=0;
        int i,j,k;
        for(i=0;i<n;i++) if(st&(1<<i)) for(j=i+1;j<n;j++)
        {
            if(st&(1<<j)) edge[st]+=!a[i][j];
        }
        conn[st]=(1LL<<edge[st])%mod;
        int lowbit=st&(-st);
        int rst=st^lowbit;
        if(rst)
        {
            for(i=(rst-1)&rst;;i=(i-1)&rst)
            {
                int nst=i^lowbit;
                conn[st]-=(i64)conn[nst]*((1LL<<edge[st^nst])%mod)%mod;
                conn[st]%=mod;
                if(i==0) break;
            }
        }
        meth[0][st]=1;
        for(i=(st-1)&st;i;i=(i-1)&st)
        {
            i64 tmp=0;
            int lowbit=i&(-i);
            int rst=i^lowbit;
            for(j=rst;;j=(j-1)&rst)
            {
                int k=j^lowbit;
                tmp+=(i64)meth[i^k][st^i]*conn[k]%mod*(edge[st^i^k]-edge[st^i]-edge[k])%mod;
                tmp%=mod;
                if(j==0) break;
            }
            meth[i][st^i]=tmp;
        }
        bico[st]=conn[st];
        if(rst)
        {
            for(i=(rst-1)&rst;;i=(i-1)&rst)
            {
                int nst=i^lowbit;
                bico[st]-=(i64)bico[nst]*meth[st^nst][nst]%mod;
                bico[st]%=mod;
                if(i==0) break;
            }
        }
    }
    
    int main()
    {
    
        int T;
        scanf("%d",&T);
        while(T--)
        {
            clr(a,0);
            scanf("%d%d",&n,&m);
            int i;
            for(i=1;i<=m;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                u--; v--;
                a[u][v]=a[v][u]=1;
            }
            for(i=0;i<(1<<n);i++) 
            {
                cal(i);
            }
            int ans=bico[(1<<n)-1];
            if(ans<0) ans+=mod;
            printf("%d
    ",ans);
        }
    }
    
  • 相关阅读:
    List集合中的对象按照某个字段去重实现
    菜单--微信提醒
    fastTime从后台传过来显示格式的处理
    彻底卸载Oracle
    关于这次安装Oracle
    关于下拉选择删选最基本一例(分享内容)
    马拉松参赛人员显示(瞬逝版)
    马拉松参赛人员旧版本最终版(私藏版)
    win 10 初始环境变量
    AngularJS输出helloworld
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/3977143.html
Copyright © 2020-2023  润新知