• [ARC101C] Ribbons on Tree 解题报告


    给出一棵 (n) 个点的树,要求将树上的节点两两配对,对于一组配对 ((u,v)) ,将 (u)(v) 的路径染色,求所有边都被染上色的方案数,答案对 (10^9+7) 取模。

    (nle 5005) ,保证 (n) 为偶数。

    这题和氪金手游那题很类似,假设 (f(S)) 是在集合 (S) 中的边都没有被染色的方案数,其中 (Sin E) ,那么答案为 (sum (-1)^{|S|} f(S))

    将一定不染色的边删去,一棵树就会被分为许多联通块,大小为 (n) 的联通块的贡献是所有配对方案的个数,也就是 (frac{frac{n(n-1)}{2} imesfrac{(n-2)(n-3)}{2} imes... imes frac{2 imes 1}{2}}{(frac{n}{2})!}=(n-1) imes(n-3) imes... imes 1) ,其中 (n) 为偶数,否则不能匹配,那么有一个简单的三维 (dp_{i,j,k}) ,代表在 (i) 的子树中, (i) 所在联通块的大小为 (j) ,删去了 (k) 条边的方案数,转移就显而易见了。

    类似氪金手游那题,可以将删去的边数这一维优化掉,因为多删一条边就会整体左移一位,放在容斥中就是整体乘上 (-1) ,可以在 (j=0) 也就是删去 (i) 到父亲的那条边时统计的答案乘上 (-1)

    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int M=5005,JYY=1e9+7;
    
    int read(){
        int x=0,y=1;char ch=getchar();
        while(ch<'0'||ch>'9') y=(ch=='-'?-1:1),ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x*y;
    }
    
    int tot=0,first[M];
    struct Edge{ int nxt,to; }e[M<<1];
    void add(int x,int y){
        e[++tot]=(Edge){first[x],y};
        first[x]=tot;
    }
    
    int dp[M][M],sz[M],tmp[M],gs[M];
    void dfs(int u,int fa){
        dp[u][1]=sz[u]=1;
        for(int i=first[u];i;i=e[i].nxt){
            int v=e[i].to;if(v==fa) continue ;
            dfs(v,u);
            for(int j=1;j<=sz[u];j++) for(int k=0;k<=sz[v];k++)
                tmp[j+k]=(tmp[j+k]+dp[u][j]*dp[v][k]%JYY)%JYY;
            sz[u]+=sz[v];
            for(int j=1;j<=sz[u];j++) dp[u][j]=tmp[j],tmp[j]=0;
        }
        for(int i=2;i<=sz[u];i+=2) dp[u][0]=(dp[u][0]-gs[i]*dp[u][i]%JYY+JYY)%JYY;
    }
    
    int n,Ans=0;
    void solve(){
        n=read();gs[0]=1;
        for(int i=2;i<=n;i+=2) gs[i]=gs[i-2]*(i-1)%JYY;
        for(int i=1;i<n;i++){
            int x=read(),y=read();
            add(x,y),add(y,x);
        }
        dfs(1,0);
        printf("%lld
    ",JYY-dp[1][0]);
    }
    
    signed main(){
        // freopen("shuju.in","r",stdin);
        solve();
    }
    
  • 相关阅读:
    为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?
    Weblogic12c安装与配置详解
    淘宝自己的前端框架KISSY(类似jquery)
    ExtJS4中initComponent和constructor的区别
    Servlet的getContextPath(), getServletPath(), getRequestURI(), getRealPath("/")
    Hash Join 一定是选择小表作为驱动表吗
    oracle for loop 简单
    oracle正则表达式
    Android开发--用户定位服务--UserLocation
    android蓝牙开发---与蓝牙模块进行通信
  • 原文地址:https://www.cnblogs.com/wzp-blog/p/14310316.html
Copyright © 2020-2023  润新知