zoukankan      html  css  js  c++  java
  • 【BZOJ 4455】 [Zjoi2016]小星星 容斥计数

    dalao教导我们,看到计数想容斥……
    卡常策略:枚举顺序、除去无效状态、(树结构)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    typedef long long LL;
    const int N=20;
    LL f[N][N];
    int n,m,d[N][N],full;
    bool yeah[N];
    int st[N],cnt;
    struct V{
      int to,next;
    }c[N<<1];
    int head[N],t;
    inline void add(int x,int y){
      c[++t].to=y,c[t].next=head[x],head[x]=t;
    }
    inline void dfs(int x,int fa){
      register int i,j,k;LL sum=0;
      for(i=head[x];i;i=c[i].next)
        if(c[i].to!=fa)
          dfs(c[i].to,x);
      for(i=1;i<=n;++i){
        if(!yeah[i]){
          f[x][i]=0;
          continue;
        }
        f[x][i]=1;
        for(j=head[x];j;j=c[j].next)
          if(c[j].to!=fa){
            sum=0;
            for(k=1;k<=cnt;++k)
              if(d[i][st[k]])
                sum+=f[c[j].to][st[k]];
            f[x][i]*=sum;
          }
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      full=(1<<n)-1;
      int i,j,x,y;
      for(i=1;i<=m;++i){
        scanf("%d%d",&x,&y);
        d[x][y]=d[y][x]=1;
      }
      for(i=1;i<n;++i){
        scanf("%d%d",&x,&y);
        add(x,y),add(y,x);
      }
      LL ans=0,sum;
      for(i=1;i<=full;++i){
        cnt=0,sum=0;
        for(j=0;j<n;++j)
          if(i&(1<<j))yeah[j+1]=true,st[++cnt]=j+1;
          else yeah[j+1]=false;
        dfs(1,0);
        for(j=1;j<=n;++j)
          sum+=f[1][j];
        ans+=(((n-cnt)&1)?-1:1)*sum;
      }
      printf("%lld
    ",ans);
      return 0;
    }
  • 相关阅读:
    Reverse Nodes in k-Group [LeetCode]
    Text Justification [LeetCode]
    Path Sum [LeetCode]
    Multiply Strings [LeetCode]
    Populating Next Right Pointers in Each Node II [Leetcode]
    013 集合
    012 元组
    02 isdecimal(), isdigit(), isnumeric()
    011 字符串的内置方法 三
    010 字符串的内置方法 二
  • 原文地址:https://www.cnblogs.com/TSHugh/p/8470499.html
Copyright © 2011-2022 走看看