题解 CF53E Dead Ends

Posted tonyshen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 CF53E Dead Ends相关的知识,希望对你有一定的参考价值。

题意:

  给一个n(n<=10)个节点的无向图,图里面有m条边,以这m条边构建生成树,求所有生成树中只含有k个度数为1的点的方案数。

题解:

  看见这个数量级就一定会想到状态压缩dp...

       那让我们设计一下状态:

       dp[i][j] 表示生成树的状态为i时,所含的度数为1的点的状态j的方案数。

  那么就可以进行状态转移了,每次有两种更新方式:

                    1:加入一条边(也就是一个新点)到原来度数为1的点,相当于替换了。

                    2:把边加到一个度数不为1的节点上。

时间复杂度:

O(能过)

废话少说上代码:

#include<bits/stdc++.h>
using namespace std;
const int maxs=(1<<11)+10;
vector<int> mapp[20];
int dp[maxs][maxs],cnt1[maxs];
int n,m,k;
void init()
    for(int i=1;i<=maxs;i++)
        for(int k=0;k<+15;k++)
            if(i&(1<<k))
               cnt1[i]++;

int main()
    init();
    scanf("%d%d%d",&n,&m,&k);
    int x,y;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y); x--;y--;
        mapp[x].push_back(y);mapp[y].push_back(x);
    
    for(int i=1;i<=(1<<n)-1;i<<=1) dp[i][i]=1;
    for(int i=1;i<=(1<<n)-1;i++)
        for(int j=i;j;--j&=i)
            if(dp[i][j])
                for(int e=0;e<n;e++)
                    if(i&(1<<e))
                        for(int r=0;r<mapp[e].size();r++)
                            int to=mapp[e][r],now;
                            if(~i&(1<<to))
                                if(cnt1[i]==1) now=i|(1<<to);
                                else now=j&~(1<<e)|(1<<to);
                                if(!(now>>to+1)) dp[i|(1<<to)][now]+=dp[i][j];
                            
                        
    long long ans=0;
    for(int i=0;i<=(1<<n)-1;i++) 
        if(cnt1[i]==k)
           ans+=dp[(1<<n)-1][i];
    printf("%lld",ans);
    return 0;

 

以上是关于题解 CF53E Dead Ends的主要内容,如果未能解决你的问题,请参考以下文章

CF1512D Corrupted Array 题解

CF398B题解

CF1051G 题解

CF1149C 题解

题解Lomsat gelral [CF600E]

题解-比赛CF1332