4455: [Zjoi2016]小星星|状压DP|容斥原理

OrzSDOIR1ak的晨神

能够考虑状压DP枚举子集,求出仅仅保证连通性不保证一一相应的状态下的方案数,然后容斥一下就是终于的答案

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<ctime>
#include<set>
#include<map>
using namespace std;
bool a[22][22];
long long f[22][22],ans;
int head[44],nxt[44],lst[44],q[44];
int n,m,tot,w;
void insert(int x,int y)
{
    lst[++tot]=y; nxt[tot]=head[x]; head[x]=tot;
    lst[++tot]=x; nxt[tot]=head[y]; head[y]=tot;
}
void dp(int x,int fa)
{
    for(int i=head[x];i;i=nxt[i])
        if(lst[i]!=fa)dp(lst[i],x);
    for(int i=1;i<=w;i++)
    {
        f[x][q[i]]=1;
        for(int j=head[x];j;j=nxt[j])
            if(lst[j]!=fa)
            {
                long long tmp=0;
                for(int k=1;k<=w;k++)
                    if(a[q[i]][q[k]])tmp+=f[lst[j]][q[k]];
                f[x][q[i]]*=tmp;
            }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        a[x][y]=a[y][x]=1;
    }
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        insert(x,y);
    }
    for(int S=1,T=1<<n;S<T;S++)
    {
        w=0;
        for(int i=1;i<=n;i++)
            if((1<<i-1)&S)q[++w]=i;
        long long sum=0;dp(1,0);
        for(int i=1;i<=w;i++)sum+=f[1][q[i]];
        if((w^n)&1) ans-=sum; else ans+=sum;
    }
    cout<<ans;
    return 0;
}

原文地址:https://www.cnblogs.com/zhchoutai/p/8410177.html

时间: 2024-10-08 07:52:47

4455: [Zjoi2016]小星星|状压DP|容斥原理的相关文章

【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum[i]}$ 减去不为强连通图的方案数得到强连通图的方案数,其中 $sum[i]$ 表示点集 $i$ 中边的数目. 考虑什么样的图不是强连通图:缩点后入度为0的强连通分量对应的点集不是全集. 枚举这些入度为0的强连通分量对应的点集,由于无法保证只有这些点构成的入度为0的强连通分量,因此需要进一步容斥.

4455[Zjoi2016]小星星 容斥+dp

4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 527  Solved: 317[Submit][Status][Discuss] Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但 通过这些细线,这颗小星星还是被串在一起,也就是这

BZOJ 2669 cqoi2012 局部极小值 状压DP+容斥原理

题目大意:给定一个n?m的矩阵,标记出其中的局部极小值,要求填入1...n?m,求方案数 <多年的心头大恨终于切掉了系列> 考虑将数字从小到大一个一个填进去 由于局部极小值最多8个,我们可以状压DP 令fi,j表示已经填完了前i个数,局部极小值的填充状态为j的方案数 预处理出cntj表示填充状态为j时共有多少位置是可以填充的(包括已填充的局部极小值位置) 那么有DP方程fi,j=fi?1,j?C1cntj?i+1+∑k∈jfi?1,j?{k} 但是问题是这样虽然保证了标记的位置都是局部最小值,

BZOJ 3812 主旋律 状压DP+容斥原理

题目大意:给定一张无向图,求这张无向图的生成子图中有多少强连通图 正着做不好做,我们考虑容斥原理 如果一个图不连通,那么这张图缩点之后一定会形成一个点数>=2的DAG 一个DAG中一定会有一些入度为0的点,我们枚举这些点的点集进行容斥 具体DP方程和细节见代码 注释写的还是比较详细的我就不多说了= = #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>

HDU 4336 容斥原理 || 状压DP

状压DP :F(S)=Sum*F(S)+p(x1)*F(S^(1<<x1))+p(x2)*F(S^(1<<x2))...+1; F(S)表示取状态为S的牌的期望次数,Sum表示什么都不取得概率,p(x1)表示的是取x1的概率,最后要加一因为有又多拿了一次.整理一下就可以了. 1 #include <cstdio> 2 const int Maxn=23; 3 double F[1<<Maxn],p[Maxn]; 4 int n; 5 int main() 6

ZOJ3305Get Sauce 状压DP,

状压DP的题目留个纪念,首先题意一开始读错了,搞了好久,然后弄好了,觉得DFS可以,最后超时,修改了很久还是超时,没办法看了一下n的范围,然后觉得状压可以,但是没有直接推出来,就记忆化搜索了一下,可是一直错,莫名奇妙,然后没办法看了一下题解,发现了下面这个比较好的方法,然后按照这个方程去推,然后敲,也是WA了好多把,写的太搓了,没人家的清楚明了,唉~也算是给自己留个纪念,状压一直做的都不太好~唉~还好理解了, 参考了  http://blog.csdn.net/nash142857/articl

poj 2411 Mondriaan&#39;s Dream(状压DP)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12232   Accepted: 7142 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

(状压dp)uva 10817 Headmaster&#39;s Headache

题目地址 1 #include <bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const int MAX=1e5+5; 5 const int INF=1e9; 6 int s,m,n; 7 int cost[125]; 8 //char sta[MAX]; 9 string sta; 10 int able[125]; 11 int dp[125][1<<8][1<<8]; 12 in

HDU5816 Hearthstone(状压DP)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an online collectible card game from Blizzard Entertainment. Strategies and luck are the most important factors in this game. When you suffer a desperate situation an