Luogu P4336 [SHOI2016]黑暗前的幻想乡 矩阵树定理+容斥原理

真是菜到爆炸。。。。容斥写反(反正第一次写qwq)


题意:$n-1$个公司,每个公司可以连一些边,求每个边让不同公司连的生成树方案数。

矩阵树定理+容斥原理(注意到$n$不是很大)

枚举公司参与与否的状态,每次重构矩阵,把参与连边的公司可以连的边写在矩阵中,然后求出方案。

代码中的$Gauss()$是辗转相除求解,$Gauss2()$是通过求逆元求解(貌似我的辗转相除更快(雾))

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#define ll long long
#define R register ll
char B[1<<15],*S=B,*T=B;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
const int M=1000000007;
using namespace std;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,ans=0,C; ll a[20][20]; vector<pair<int,int> > q[20];
#define pb push_back 
inline int Gauss() { ll ans=1;
    for(R i=1;i<n;++i) {
        for(R j=i+1;j<n;++j) while(a[j][i]) {
            ll t=a[i][i]/a[j][i];
            for(R k=i;k<n;++k) (a[i][k]-=t*a[j][k])%=M;
            swap(a[i],a[j]); ans=-ans;
        } ans=(ans*a[i][i])%M; if(!ans) return 0;
    } return (ans+M)%M;
} 
inline ll Inv(int x) {
    if(x==1) return 1; if(x<1) return 0;
    return (M-M/x*Inv(M%x))%M;
}
inline int Gauss2() { register ll ans=1;
    for(R i=1;i<n;++i) for(R j=i+1;j<n;++j) {
        if(!a[i][i]) return 0; if(!a[j][i]) continue;
        register ll t=(ll)a[j][i]*Inv(a[i][i]%M)%M;
        for(R k=i;k<n;++k) a[j][k]=((a[j][k]-t*a[i][k])%M+M)%M;
    } for(R i=1;i<n;++i) ans=ans*a[i][i]%M; return ans;
}
signed main() { 
    n=g(); for(R i=1,x;i<n;++i) { x=g(); 
        for(R j=1,u,v;j<=x;++j) u=g(),v=g(),q[i].pb(make_pair(u,v));
    } C=1<<(n-1);
    for(R i=0;i<C;++i) { R cnt=0; memset(a,0,sizeof(a));
        for(R j=1;j<n;++j) if(i&(1<<j-1)) {
            for(R k=0,u,v;k<q[j].size();++k) 
                u=q[j][k].first,v=q[j][k].second,
                ++a[u][u],++a[v][v],--a[u][v],--a[v][u];
            ++cnt;
        } if((n-cnt)&1) ans=(ans+Gauss2())%M;
        else ans=(ans-Gauss2()+M)%M;
    } printf("%lld\n",ans);
}

2019.06.02

 

posted @ 2019-06-02 22:03  LuitaryiJack  阅读(112)  评论(0编辑  收藏  举报