题意:一棵$n$个点的树($n$是偶数),把所有点分成$\frac n2$对,每对点都在树上路径涂色,问有多少种配对方式使得所有边都被涂上颜色

考虑容斥,设$E$是整棵树的边集,$F\subseteq E$,定义$f(F)$表示有多少种配对满足$F$中的边都不被涂色,那么答案是$\sum\limits_{F\subseteq E}(-1)^{|F|}f(F)$

对于一个给定的$F$,我们容易计算$f(F)$:设删去$F$中边后形成的$|F|+1$个连通块的大小为$n_{1\cdots|F|+1}$,那么$f(F)=\prod\limits_{i=1}^{|F|+1}g(n_i)$,其中$g(n)=[2|n](n-1)!!$

现在我们要求所有的$f(F)$,考虑DP

设$f_{i,j,k}$表示在$i$的子树中,删边数奇偶性为$k$,$i$所在连通块大小为$j$的配对方案数,注意这里的方案数是不管$i$所在连通块是如何配对的,即答案为$\sum\limits_{i=1}^n(f_{root,i,0}-f_{root,i,1})g_i$

转移就很自然了,枚举子树,按当前边删不删进行转移,时间复杂度$O(n^2)$

#include<stdio.h>
#include<string.h>
typedef long long ll;
const int mod=1000000007;
int mul(int a,int b){return(ll)a*b%mod;}
int ad(int a,int b){return(a+b)%mod;}
void inc(int&a,int b){(a+=b)%=mod;}
int h[5010],nex[10010],to[10010],M;
void add(int a,int b){M++;to[M]=b;nex[M]=h[a];h[a]=M;
}
int siz[5010],f[5010][5010][2],g[5010],p[5010][2];
void dfs(int fa,int x){int i,j,k,t1,t2;siz[x]=1;f[x][1][0]=1;for(i=h[x];i;i=nex[i]){if(to[i]!=fa){dfs(x,to[i]);memset(p,0,sizeof(p));for(j=1;j<=siz[x];j++){for(k=1;k<=siz[to[i]];k++){t1=ad(mul(f[x][j][0],f[to[i]][k][0]),mul(f[x][j][1],f[to[i]][k][1]));t2=ad(mul(f[x][j][0],f[to[i]][k][1]),mul(f[x][j][1],f[to[i]][k][0]));//connectinc(p[j+k][0],t1);inc(p[j+k][1],t2);//removeinc(p[j][0],mul(g[k],t2));inc(p[j][1],mul(g[k],t1));}}siz[x]+=siz[to[i]];memcpy(f[x],p,sizeof(p));}}
}
int main(){int n,i,x,y,s;scanf("%d",&n);for(i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}g[0]=1;for(i=2;i<=n;i+=2)g[i]=mul(g[i-2],i-1);dfs(0,1);s=0;for(i=2;i<=n;i+=2)inc(s,mul(g[i],f[1][i][0]-f[1][i][1]));printf("%d",ad(s,mod));
}

转载于:https://www.cnblogs.com/jefflyy/p/9569513.html

[ARC101E]Ribbons on Tree相关推荐

  1. ARC101E - Ribbons on Tree

    题目链接 ARC101E - Ribbons on Tree 题解 令边集\(S \subseteq E\) 设\(f(S)\)为边集S中没有边被染色的方案数 容斥一下,那么\(ans = \sum_ ...

  2. ARC101E Ribbons on Tree 容斥原理+dp

    题目链接 https://atcoder.jp/contests/arc101/tasks/arc101_c 题解 直接容斥.题目要求每一条边都被覆盖,那么我们就容斥至少有几条边没有被覆盖. 那么没有 ...

  3. ARC101E Ribbons on Tree

    Problem AtCoder Solution 发现ARC也有挺多比较有意思的题目-- 直接统计是很麻烦的,所以我们不妨考虑容斥.如果有F(S)F(S)F(S)表示SSS集合中的边未被覆盖的答案,那 ...

  4. ARC101E - Ribbons on Tree 树形DP

    题意 在一个有nnn个点的树上,nnn为偶数,把所有的点两两配对,配对点之间的路径染色,求把树上所有路径染色的方案数,对1e9+71e9 + 71e9+7取模 这个题完全想不出来 最后还是RudyGa ...

  5. ARC101E Ribbons on Tree 树形dp 容斥

    题目链接 题意: 给你一棵nnn个点的树,nnn是偶数,把这些点分成n2\frac{n}{2}2n​个点对,每个点对会把路径上的所有边覆盖,问你每条边至少覆盖一次有多少种配对方式.n<=5000 ...

  6. 【ARC101E】Ribbons on Tree(树形DP,容斥原理)

    Description 给定一棵点数为偶数的树,要求有多少种将点两两配对的方案使得每一条边至少被一对匹配点之间的最短路径覆盖. Solution 根本想不到的DP系列. 首先考虑一个容斥,设F(E)F ...

  7. 【题解】arc101 C - Ribbons on Tree

    很棘手的树形 dpdpdp . 设 dp[u][x]dp[u][x]dp[u][x] 表示以 uuu 为根的子树,有 xxx 个节点失配的方案数.这样时间复杂度 O(n3)O(n^3)O(n3) . ...

  8. AT4352-[ARC101C] Ribbons on Tree【dp,容斥】

    正题 题目链接: https://www.luogu.com.cn/problem/AT4352 https://atcoder.jp/contests/arc101/tasks/arc101_c 题 ...

  9. ARC 101 E - Ribbons on Tree

    题意与数据范围 给定 \(n\) 个点的树,你需要把这些点分成 \(\frac{n}{2}\) 组,每组恰好 \(2\) 个点,且每个点在至多一组中. 称一个分组方案是好的,当且仅当:如果我们把每对点 ...

最新文章

  1. java 流的概念_举例讲解Java中的Stream流概念
  2. 计算机的图形渲染机制
  3. 山果(转载《人民日报》)
  4. Flutter开发之ListView使用第三方pull_to_refresh加载更多(36)
  5. 【探索PowerShell 】【三】PowerShell下使用Aliases
  6. 基于FFmpeg音视频流同步
  7. 我们已经不用 AOP 做日志很久了!
  8. [NTU-Machine-learning-note]1 Introduction(2)
  9. TCP/IP / 如何保证数据包传输的有序可靠?
  10. java客户端作为kafka生产者测试
  11. Python格式化函数format详解
  12. 数据治理资深大咖分享:一文详解数据标准管理
  13. php 多态有什么用,php面向对象多态的介绍与优势
  14. 顶尖技术专家严选,15场前沿论坛思辨,2019中国大数据技术大会邀您共赴!
  15. 2017-2018-1 20155320 嵌入式C语言——时钟
  16. 手机12306买卧铺下铺技巧_手机上买火车票怎么买下铺
  17. Unity3D简单换装系统
  18. 知识付费垂直细分-育儿知识付费社区
  19. ES6转化ES5方法(处理低版本手机白屏等兼容问题)
  20. 在线编译linux,在线就能用的Linux我给你找好了

热门文章

  1. htc+820+android+5.0,htc 820s和htc one m8哪个好?两者有什么区别?
  2. java题型_java一些经典题型
  3. 前22年的Loser,后4年和自己赛跑的人 | 最惨前端面经
  4. 20200228视频播放器的字幕支持
  5. U盘安装WIN10时显示 windows无法安装到这个磁盘 选中的磁盘采用GPT分区形式
  6. 嘚瑟一下,我的书上电视了!
  7. to B和to C产品的区别
  8. P2327 [SCOI2005]扫雷(递推)
  9. Android PCM 播放全是噪音滋滋滋
  10. 如何在 PC 上识别微信二维码