• bzoj4596 [Shoi2016]黑暗前的幻想乡


    如果要用矩阵树的话是无法限制公司个数的,发现数据范围十分小,于是考虑容斥,最后答案就等于$n-1$个公司的方案数-$n-2$个公司的方案数+$n-3$个公司的方案数$...$,然后跑矩阵树就好了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<vector>
     7 #define N 20
     8 #define pb push_back
     9 #define mp make_pair
    10 #define mod 1000000007
    11 #define int long long
    12 using namespace std;
    13 int a[N][N],n;
    14 int gauss(){
    15     for(int i=1;i<=n;i++)
    16         for(int j=1;j<=n;j++)
    17             (a[i][j]+=mod)%=mod;
    18     /*for(int i=1;i<=n;i++){
    19         for(int j=1;j<=n;j++)
    20             printf("%lld ",a[i][j]);
    21         puts("");
    22     }puts("");*/
    23     int ans=1;
    24     for(int k=1;k<n;k++){
    25         for(int i=k+1;i<n;i++){
    26             while(a[i][k]){
    27                 int t=a[k][k]/a[i][k];
    28                 for(int j=k;j<n;j++){
    29                     a[k][j]=(a[k][j]-t*a[i][j]%mod+mod)%mod;
    30                     swap(a[k][j],a[i][j]);
    31                 }
    32                 ans=(-ans+mod)%mod;
    33             }
    34         }
    35         ans=(ans*a[k][k])%mod;
    36     }
    37     //printf("%lld
    ",ans);
    38     return ans;
    39 }
    40 void add(int x,int y){
    41     a[x][x]++;a[y][y]++;
    42     a[x][y]--;a[y][x]--;
    43 }
    44 vector<pair<int,int> >v[N];
    45 int bit[20];
    46 int getnum(int x){
    47     int cnt=0;
    48     while(x){cnt++;x^=x&-x;}
    49     return cnt;
    50 }
    51 signed main(){
    52     bit[0]=1;
    53     for(int i=1;i<=17;i++)bit[i]=bit[i-1]<<1;
    54     scanf("%lld",&n);
    55     for(int i=1,num;i<n;i++){
    56         scanf("%lld",&num);
    57         for(int j=1,x,y;j<=num;j++){
    58             scanf("%lld%lld",&x,&y);
    59             v[i].pb(mp(x,y));
    60         }
    61     }
    62     int tot=0;
    63     for(int i=0;i<bit[n-1];i++){
    64         memset(a,0,sizeof a);
    65         for(int j=1;j<=n;j++)if(i&bit[j-1]){
    66             for(int k=0,x,y;k<v[j].size();k++){
    67                 x=v[j][k].first,y=v[j][k].second;
    68                 add(x,y);
    69             }
    70         }
    71         int now=gauss();
    72         if((getnum(i)&1)^((n-1)&1))tot=(tot-now+mod)%mod;
    73         else tot=(tot+now)%mod;
    74     }
    75     printf("%lld
    ",tot);
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    shell脚本100例、练习使用
    shell基础编程
    mysql基础理论知识
    Docker 基础
    python基础之类(面向对象编程)
    python基础之函数
    python基础之认知及编码
    python基础之数据类型
    python基础之注意事项
    1.linux使用基础
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8185870.html
Copyright © 2020-2023  润新知