zoukankan      html  css  js  c++  java
  • bzoj4596: [Shoi2016]黑暗前的幻想乡

    一波卡线AC美滋滋。。

    这题以前看过,但是不会矩阵树定理就弃了

    今天再看还是不是很会。。

    状压一波,0/1表示这个公司取还是不取,那么就把这个公司能够修的边放进图弄基尔霍夫矩阵求行列式,但是这样并不能保证这个公司必定被取

    考虑容斥,就要减去这个公司一定不取的情况……

    假如奇偶性和n-1就加,否则就减

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib> 
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const LL mod=1e9+7;
    LL MOD(LL x){return (x%mod+mod)%mod;}
    
    int n;
    LL kf[20][20];
    LL gethls()
    {
        LL ans=1,tp=1;
        for(int i=2;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                int x=i,y=j;
                while(kf[y][i]!=0)
                {
                    LL t=kf[x][i]/kf[y][i];
                    for(int k=i;k<=n;k++)
                        kf[x][k]=MOD(kf[x][k]-MOD(kf[y][k]*t));
                    swap(x,y);
                }
                if(x!=i)
                {
                    tp=0-tp;
                    for(int k=2;k<=n;k++)
                        swap(kf[x][k],kf[y][k]);
                }
            }
            ans=MOD(ans*kf[i][i]);
        }
        ans=MOD(ans*tp);
        return ans;
    }
    
    struct repair
    {
        int x,y;
    }c[20][410];int clen[20];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d",&clen[i]);
            for(int j=1;j<=clen[i];j++)
                scanf("%d%d",&c[i][j].x,&c[i][j].y);
        }
        
        int lim=(1<<(n-1))-1;LL ans=0;
        for(int zt=0;zt<=lim;zt++)
        {
            int o=0;
            memset(kf,0,sizeof(kf));
            for(int i=1;i<=n;i++)
            {
                if( (zt& (1<<(i-1)) )>0)
                {
                    o++;
                    for(int j=1;j<=clen[i];j++)
                    {
                        kf[c[i][j].x][c[i][j].x]++;
                        kf[c[i][j].y][c[i][j].y]++;
                        kf[c[i][j].x][c[i][j].y]--;
                        kf[c[i][j].y][c[i][j].x]--;
                    }
                }
            }
            if((n-1)%2==o%2)ans=MOD(ans+gethls());
            else ans=MOD(ans-gethls());
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    小D课堂
    小D课堂
    小D课堂
    小D课堂
    小D课堂
    c++ , const对象中的变量不能被修改
    C++,常成员函数
    c++,给常成员变量赋值
    C++中,引用作为函数参数
    C++中,如何定义和使用指向成员函数的指针
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8933750.html
Copyright © 2011-2022 走看看