• #1071 : 小玩具


    描述

    某天,高富帅clj送了他的朋友jzp一个小玩具。

    这个玩具可以被看成是一个n个点,m条边的没有重边和自环的无向图。对于每一条边,有闪光和黑暗两种状态。

    jzp可以把一些边设为闪光,一些边设为黑暗。当jzp设置完成以后,这个玩具会按照如下方式计算出一个分数。首先称闪光边和这n个点组成的图为导出子图,然后玩具会找出导出子图中最大的联通分量的大小,当做分数输出。

    jzp有一天很闲,他尝试了所有的2m种边的设置方式(每个边为闪光或者黑暗),并且计算出了每种分数的出现次数。写在了一张纸上。

    但是很不走运的是,这张纸某一天被他给搞丢了。现在我告诉你这个图,你能帮助他重新计算出每种分数的出现次数吗?

    输入

    第一行两个数n(1<=n<=15)和m(0<=m<=n(n-1)/2),分别表示玩具中图的点数和边数。接下来m行,每行两个数a和b,表示a和b之间有一条边。

    点从1开始标号。

    输出

    一共输出n行,第i行表示分数i的出现次数,对10^9+7取模。

    样例输入

    3 3
    1 2
    1 3
    2 3

    样例输出

    1
    3
    4



    妈妈做WJMZBER的题鸭梨山大。
    首先转化问题,设ans[k]表示所有连通分量大小均<=k的方案。
    则最大连通分量为k的方案转化成ans[k]-ans[k-1]
    然后就可以DP了,考虑从一个集合S中慢慢剥离连通分量。设f[S]表示将集合S中的点分配且满足要求的方案。
    枚举S的最低位的元素x所在的集合S0,则f[S]=(|S|<=k?g[S]:0)+∑(f[S0]*g[S0]|S0⊂S,|S0|<=k,{x}⊂S)
    其中g[S]表示S中的点均连通的方案数。
    计算g[S]是我们可以用容斥原理,将S中的点均连通的方案数转化成全集-S中的点不连通的方案数。计算时依然枚举S的最低位的元素x所在的集合S0,算算就行了。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=16;
    const int mod=1000000007;
    typedef long long ll;
    int n,m,es[1<<maxn],u[maxn*maxn],v[maxn*maxn],cnt[1<<maxn];
    ll g[1<<maxn],f[1<<maxn],xp[maxn*maxn],ans[maxn];
    int main() {
        n=read();m=read();
        rep(i,1,m) u[i]=read()-1,v[i]=read()-1;
        rep(S,0,(1<<n)-1) {
            rep(i,0,n-1) if(S&(1<<i)) cnt[S]++;
            rep(i,1,m) if((S&(1<<u[i]))&&(S&(1<<v[i]))) es[S]++;
        }
        xp[0]=1;
        rep(i,1,m) xp[i]=(xp[i-1]<<1)%mod;
        g[0]=1;
        rep(S,1,(1<<n)-1) {
            int bit=S&-S;
            for(int S0=(S-1)&S;S0;S0=(S0-1)&S) if(bit&S0) {
                (g[S]+=g[S0]*xp[es[S^S0]])%=mod;
            }
            g[S]=(xp[es[S]]-g[S]+mod)%mod;
        }
        rep(T,1,n) {
            f[0]=1;
            rep(S,1,(1<<n)-1) {
                f[S]=cnt[S]<=T?g[S]:0;int bit=S&-S;
                for(int S0=(S-1)&S;S0;S0=(S0-1)&S) if((bit&S0)&&cnt[S0]<=T) (f[S]+=f[S0^S]*g[S0])%=mod;
            }
            ans[T]=f[(1<<n)-1];
            if(T) printf("%lld
    ",(ans[T]-ans[T-1]+mod)%mod);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    链表操作 —— 61_链表旋转
    链表操作 —— 25_k个一组翻转链表
    链表操作 —— 19_删除链表倒数第N个结点
    链表操作 —— 1. 2_两数相加
    Hash相关 —— 2. 387_字符串中的第一个唯一字符
    Hash相关 —— 1. 1_两数之和
    Maven02-Maven 仓库、生命周期、插件、镜像
    mvn test 运行测试不显示测试统计信息和测试结果
    Maven 概述
    Spring源码03---parseDefaultElement
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4802545.html
Copyright © 2020-2023  润新知