zoukankan      html  css  js  c++  java
  • #矩阵树定理,高斯消元,容斥定理#洛谷 4336 [SHOI2016]黑暗前的幻想乡

    题目


    分析

    这很明显是矩阵树定理,但是每个建筑公司都恰好修建一条边非常难做,
    考虑如果一个建筑公司在某个方案中并没有恰好修建一条边,
    那么这种方案一定能在不选其它任意一个公司的方案中被减掉,
    那就可以用容斥定理做,枚举选择公司的二进制状态,求出基尔霍夫矩阵


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int mod=1000000007;
    int a[18][18],Aa[17][18][18],xo[65536],n,ans,all;
    inline signed iut(){
        rr int ans=0; rr char c=getchar();
        while (!isdigit(c)) c=getchar();
        while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
        return ans;
    }
    inline signed ksm(int x,int y){
    	rr int ans=1;
    	for (;y;y>>=1,x=1ll*x*x%mod)
    	    if (y&1) ans=1ll*ans*x%mod;
    	return ans;
    }
    inline void MO(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
    inline void Mo(int &x,int y){x=x<y?x-y+mod:x-y;}
    inline signed Gauss(int n){
    	rr int ans=1;
        for (rr int i=1,p=1;i<=n;p=++i){
        	for (rr int j=i+1;j<=n;++j)
        	if (a[j][i]>a[p][i]) p=j;
        	if (p!=i){
    		    for (rr int j=1;j<=n;++j)
    		        swap(a[i][j],a[p][j]);
    		    ans=mod-ans;
    		}
    		if (!a[i][i]) return 0;
    		ans=1ll*ans*a[i][i]%mod;
    		rr int invt=ksm(a[i][i],mod-2);
        	for (rr int j=1;j<=n;++j)
    		if (i!=j){
        		rr int elim=1ll*a[j][i]*invt%mod;
        		for (rr int k=i;k<=n;++k)
        		    Mo(a[j][k],1ll*elim*a[i][k]%mod);
    		}
    	}
    	return ans;
    }
    signed main(){
    	n=iut(),all=1<<(n-1);
    	for (rr int i=1;i<n;++i)
    	for (rr int CNT=iut();CNT;--CNT){
    		rr int x=iut(),y=iut();
    		++Aa[i][x][x],Mo(Aa[i][x][y],1);
    		++Aa[i][y][y],Mo(Aa[i][y][x],1);
    	}
    	for (rr int S=1;S<all;++S) xo[S]=xo[S&(S-1)]+1;
    	for (rr int S=1;S<all;++S){
    		memset(a,0,sizeof(a));
    		for (rr int k=0;k<n;++k)
    		if ((S>>k)&1){
    			for (rr int i=1;i<=n;++i)
    			for (rr int j=1;j<=n;++j)
    			    MO(a[i][j],Aa[k+1][i][j]);
    		}
    		rr int t=Gauss(n-1);
    		if ((xo[S]^n)&1) MO(ans,t);
    		    else Mo(ans,t);
    	}
    	return !printf("%d",ans);
    }
    
  • 相关阅读:
    第八次作业
    第七次作业2
    jsp第十一次作业
    jsp第十次作业
    jsp第九次作业
    jsp第八次作业
    jsp第七次作业
    jsp第六次作业
    软件测试第二次作业
    jsp第五次作业
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13922540.html
Copyright © 2011-2022 走看看