zoukankan      html  css  js  c++  java
  • 【bzoj4596】黑暗前的幻想乡

    把每个公司能连的边都看做独立的边,即在所有能连的边里随便连,矩阵树。

    显然有不合法的情况,每个公司只能连一条边,考虑容斥:

    ans=sigma随便连-sigma一个公司不连+sigma两个公司不连-sigma三个公司不连……

    容斥写错了safufu地调了半天消元QAQ

    #include<bits/stdc++.h>
    #define maxn 20
    #define MOD 1000000007
    #define ll long long
      
    using namespace std;
      
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
      
    int a[maxn][maxn],D[maxn][maxn],A[maxn][maxn];
      
    int gauss(int n){
        int ret=1;
        for(int i=1;i<=n;++i){
            for(int j=i+1;j<=n;++j){
                int A=a[i][i],B=a[j][i];
                while(B){
                    int t=A/B;A%=B;swap(A,B);
                    for(int k=i;k<=n;++k)a[i][k]=(a[i][k]-1ll*t*a[j][k]%MOD)%MOD;
                    for(int k=i;k<=n;++k)swap(a[i][k],a[j][k]);
                    ret=-ret;
                }
            }
            if(!a[i][i])return 0;
            ret=1ll*ret*a[i][i]%MOD;
        }
        return (ret+MOD)%MOD;
    }
      
    int n,s[maxn],num[maxn],u[maxn][maxn*maxn],v[maxn][maxn*maxn];
      
    void build(){
        memset(D,0,sizeof(D));
        memset(A,0,sizeof(A));
        for(int i=1;i<n;++i)if(s[i]){
            for(int j=1;j<=num[i];++j){
                int f1=u[i][j],f2=v[i][j];
                ++D[f1][f1];++D[f2][f2];
                ++A[f1][f2];++A[f2][f1];
            }
        }
        for(int i=1;i<n;++i)
            for(int j=1;j<n;++j)
                a[i][j]=D[i][j]-A[i][j];
    }
      
    int ans;
      
    void dfs(int p,int f){
        if(p>=n){
            f=n-1-f;
            if(f&1)f=-1;else f=1;
            build();int gs=gauss(n-1);
            ans=(ans+f*gs)%MOD;
            return;
        }
        s[p]=1;
        dfs(p+1,f+1);
        s[p]=0;
        dfs(p+1,f);
    }
      
    int main(){
        n=read();
        for(int i=1;i<n;++i){
            num[i]=read();
            for(int j=1;j<=num[i];++j){
                u[i][j]=read();v[i][j]=read();
            }
        }
        dfs(1,0);
        printf("%d
    ",(ans%MOD+MOD)%MOD);
        return 0;
    }
  • 相关阅读:
    21.Merge Two Sorted Lists 、23. Merge k Sorted Lists
    34. Find First and Last Position of Element in Sorted Array
    leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、301. Remove Invalid Parentheses
    31. Next Permutation
    17. Letter Combinations of a Phone Number
    android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
    oc 异常处理
    oc 类型判断
    oc Delegate
    oc 协议
  • 原文地址:https://www.cnblogs.com/illya/p/7603521.html
Copyright © 2011-2022 走看看