#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\n",(ans[T]-ans[T-1]+mod)%mod);
    }
    return 0;
}

时间: 2024-10-20 22:51:24

#1071 : 小玩具的相关文章

hihocoder #1071 : 小玩具

闻所未闻的$dp$神题(我不会的题) 令$f[S][i]$表示子集状态为$S$,且$S$中最大联通块恰好为$i$的方案数 考虑转移,我们枚举$S$中最小的元素$v$来转移,这样就能不重 $f[S][i] = \sum\limits_{T \in S \;and\;v \in T} f[T][...] * C[S \wedge T]$ 由于这么递归转移不好确定后面的状态,因此我们可以递推转移,在代码中有所体现 $C[S]$表示将$S$联通的方案数 我们考虑容斥,用全集减去所有不联通的方案数,我们考

开源项目之小玩具---各种机器人开源硬件

一些小玩具的网站 作者: doskey 日期: 2012 年 10 月 10 日1 条评论 TinkerForge - http://www.tinkerforge.com一个开源机器人的网站.Made In Germany.东西很好只是太贵. Arduino – http://www.arduino.cc著名的开源电路项目.价格不便宜.适合爱折腾的同学. Raspberry Pi – http://www.raspberrypi.org现在最火爆的开源电路板——树莓派.东西便宜,可玩性高,但是

自己实现的依赖注入小玩具

package app10e.util; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.DataSources; import app10d.action.GetProductsAction; import app10d.action.SaveProductAction; import app10d.dao.ProductDAO;

一个小玩具:NDK编译FFmpeg的例子

FFmpeg NDK编译 和最简单的APK 准备 硬件: 一台电脑,实验在Lenovo T430上 一个Android设备,实验在 三星S3/A7 编译环境: Ubuntu 14.04 (ant\java等命令必须支持) 工具包: NDK: https://dl.google.com/android/ndk/android-ndk32-r10b-linux-x86_64.tar.bz2 SDK:https://dl.google.com/android/adt/adt-bundle-linux-

魔方(小玩具)

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> *{ padding: 0; margin: 0; } height: 100%; } body{ position: relative; perspective: 1000px; } .wrap

unity编程——小玩具

今天做了一个萤火虫飞舞效果,这个问题类似于一道算法题:一个点想移动到平面上任意一点,但是自身有一个旋转角度限制,每一次旋转时,最大旋转角度是 maxRotateAngle,思维延时(即两次连续执行自身指令的间隔)是 float gap. 大致思路是: 建立了四个指令,分别是: Blink()—— 萤火虫屁股发光,是闪烁的......闪烁的... Move()——(默认使用 Vector2 curSpeed 作为移动增量) ComputeDir() —— 根据目标位置,计算当前运动方向,因为旋转角

一个小玩具:Python调用Mysql

1. ubuntu安装MySQL how to install:$ sudo apt-get install mysql-server$ sudo apt-get install mysql-client$ sudo apt-get install libmysqlclient-dev#python DB API$  sudo apt-get install python-mysqldb check:sudo netstat -tap | grep mysql run:mysql -u root

微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器

我的微信开发者工具 开篇语 好不容易,终于把所有的基础课程全部看完了!昨天,我很高兴地开始了看别人做的项目进行深度的学习.其实也说不上是项目吧,更多的像是一种给新手看的示例代码.然后我在这些代码上面进行我自己的改进.最后也就有了接下来我会给大家带来的这篇文章中的项目.这个项目是完整的,它包括了一个原本的示例代码中带着的莫名其妙的动画组件(可能是为了更多额展示微信小程序的控件体系)以及跑步的组件,还有我后来自己加上去的一个音乐播放组件.总共也就有了三个的功能:动画效果展示:跑步的定时以及定位功能:

基于MNIST手写数字数据集的数字识别小程序

30行代码奉上!(MNIST手写数字的识别,识别率大约在91%,简单尝试的一个程序,小玩具而已) 1 import tensorflow.examples.tutorials.mnist.input_data as input_data 2 import tensorflow as tf 3 mnist = input_data.read_data_sets('/temp/', one_hot=True) 4 5 #设置 6 x = tf.placeholder(tf.float32,[None