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

    Description

    (n-1) 个边集,从每个边集里选一条边,使得有 (n) 个点的图 (G) 连通,求方案数。

    Solution

    如果直接把所有边建好矩阵跑 Matrix-tree 的话,可能会有多条边来自同一边集,同时有些边集没有选到。所以强制不选其中 (k) 个边集的边,然后建图,每次都跑 Matrix-tree,再乘上容斥系数 ((-1)^k)。这样就得到了答案。

    复杂度 (O(2^nn^3log n))。这样算下来有十多亿,但上界很宽,跑不满。实际上一秒就出来了。

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define N 20
    #define ll long long
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    ll ans=0,a[N][N];
    
    struct E{
        int u,v;
        inline void readin(){u=read(),v=read();}
        inline void add(){a[u][u]++,a[v][v]++,a[u][v]--,a[v][u]--;}
        inline void del(){a[u][u]--,a[v][v]--,a[u][v]++,a[v][u]++;}
    }sta[N][N*N];
    
    int n,top[N];
    ll b[N][N];
    
    const ll Mod=1000000007ll;
    
    ll gs(){
        int S=n-1;
        ll ret=1;
        for(int i=1;i<=S;i++)
            for(int j=1;j<=S;j++)
                b[i][j]=(a[i][j]%Mod+Mod)%Mod;
        for(int i=1;i<=S;i++){
            for(int j=i+1;j<=S;j++)
                while(b[j][i]){
                    ll t=b[i][i]/b[j][i];
                    for(int k=i;k<=S;k++)
                        b[i][k]=(b[i][k]-t*b[j][k]%Mod+Mod)%Mod;
                    swap(b[i],b[j]),ret=-ret;
                }
            ret=(ret*b[i][i]%Mod+Mod)%Mod;
            if(!ret) return 0;
        }
        return ret;
    }
    
    void dfs(int st,int op){
        if(st==n) ans=(ans+op*gs()%Mod+Mod)%Mod;
        else{
            for(int i=1;i<=top[st];i++)
                sta[st][i].add();
            dfs(st+1,op);
            for(int i=1;i<=top[st];i++)
                sta[st][i].del();
            dfs(st+1,-op);
        }
    }
    
    int main(){
        n=read();
        for(int i=1;i<n;i++){
            top[i]=read();
            for(int j=1;j<=top[i];j++)
                sta[i][j].readin();
        }
        dfs(1,1);
        printf("%lld",ans);
    }
    
  • 相关阅读:
    servletContext
    解决Response输出时乱码
    servletConfig
    服务器和浏览器交互过程
    myeclipse配置
    servlet
    http协议
    配置虚拟主机
    配置主页
    开网站步骤
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14348126.html
Copyright © 2011-2022 走看看