题目大意

给定一颗\(n\le 100\)个点的图,可以进行随机游走,求游走\(k=0...n\)个点的方案数

游走的规则是:每次只能访问一个度数\(\le 1\)的点,并将其删除

分析

看完傻眼

问题1:随便顺序

问题2:稍微分析一下,发现环内的点不能选,甚至两个环的路径上的点都不能选

做法

对于问题2:并不需要缩点加奇怪处理找到不能选的点,只需要topu即可

可以发现,不可选集合会将联通快分成若干棵树,且不存在一棵树被不可选集合夹在中间的情况(这样的话这棵树就不可选,矛盾),于是划分出来的树一定所有节点的可选

整道题中,树有两类

1:有根树,即树根与一个不可选点相连,这时必须选完树中所有点才能选树根

2:无根树,即该联通快内不存在不可选点,此时哪个节点最后选择都可以

对于问题1:依然是树形背包dp

f[i][j]表示\(i\)子树中,选了\(j\)个点的方案数

dp合并的时候乘上组合数就好了

还是老问题:

\[\binom {a_1+a_2+..+a_n}{a_1~,~a_2~,~..~,~a_n}=\binom{a_1+a_2+..+a_n}{a_n}\cdots\binom{a_1+a_2}{a_2}\binom{a_1}{0}
\]

对于有根树是这样

那么对于无根树呢

我们枚举哪个节点最后删除,即对于树上每个点作为根求一次,dp值对应位加起来

此时对于\(n\)个点删除了\(i\)个点的情况,\(n-i\)个点作为根的时候都统计到了它,除一下

特别的,对于\(n\)个点删除了\(n\)个点的情况,不用除(也不能除n-n=0),因为这样既没有算重,也没有算漏,每个点最后删除的情况都枚举了,恰好就是所有情况

姿势

以后背包dp转移都可以写结构体,方便快捷

for循环边界思考过程:

枚举\(i+j=k\)的\(k\),再枚举\(i\)

满足不等式\(0\le i\le n\),\(0\le k-i \le m\)

以及组合数注意C(x,y)时特判x<y否则越界

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int M=107;
const int N=1e4+7;
const int Q=1e9+9;
typedef long long LL; inline int pls(int x,int y){return ((LL)x+y)%Q;}
inline int mns(int x,int y){return pls(x,Q-y);}
inline int mul(int x,int y){return 1LL*x*y%Q;} inline int ri(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
} int n,m;
int inv[M],fac[M],ifac[M];
int vis[M],ok[M],deg[M];
vector<int>pt; inline int C(int x,int y){return (x>=y) ? mul(fac[x],mul(ifac[y],ifac[x-y])) : 0;} void init(){
int i;
for(inv[1]=1,i=2;i<=n;i++) inv[i]=mul(inv[Q%i],Q-Q/i);
for(fac[0]=1,i=1;i<=n;i++) fac[i]=mul(fac[i-1],i);
for(ifac[0]=1,i=1;i<=n;i++) ifac[i]=mul(ifac[i-1],inv[i]);
} struct vec{
int g[M],te;
struct edge{
int y,nxt;
edge(int _y=0,int _nxt=0){y=_y,nxt=_nxt;}
}e[N<<1];
vec(){memset(g,0,sizeof(g));te=1;}
inline void push(int x,int y){e[++te]=edge(y,g[x]);g[x]=te;}
inline void push2(int x,int y){push(x,y);push(y,x);}
inline int& operator () (int x){return g[x];}
inline edge& operator [] (int x){return e[x];}
}e; struct node{
int f[M],n;
node(){n=0;memset(f,0,sizeof f);}
void clear(){memset(f,0,sizeof f);n=0;}
inline int& operator [] (int x){return f[x];}
node operator *=(node &y){
int i,j,tp;
for(i=n+y.n;i>=0;i--){
for(tp=0,j=max(i-n,0);j<=min(i,y.n);j++)
tp=pls( tp, mul(C(i,j),mul(y[j],f[i-j])) );
f[i]=tp;
}
n+=y.n;
}
node operator +=(node &y){
int i;
for(i=0;i<=y.n;i++) f[i]=pls(f[i],y[i]);
n=max(n,y.n);
}
}ans,sum,f[M]; void topu(){
int i,h=0,t=0,x,p,y;
static int q[M];
for(i=1;i<=n;i++) if(deg[i]<=1) q[++t]=i;
while(h!=t){
x=q[++h];
ok[x]=1;
for(p=e(x);p;p=e[p].nxt){
y=e[p].y;
if(!ok[y]&&(--deg[y])<=1) q[++t]=y;
}
}
} void dfs(int x,int fa){
vis[x]=1;
f[x].clear(); f[x][0]=1;
int p,y;
for(p=e(x);p;p=e[p].nxt)
if((y=e[p].y)!=fa){
dfs(y,x);
f[x]*=f[y];
}
f[x].n++;
f[x][f[x].n]=f[x][f[x].n-1];
} void getpt(int x,int fa){
pt.push_back(x);
for(int p=e(x);p;p=e[p].nxt) if(e[p].y!=fa) getpt(e[p].y,x);
} void gao(int x,int fa){
if(fa!=0){
dfs(x,fa);
ans*=f[x];
}
else{
int i,num;
pt.clear(); getpt(x,0); sum.clear();
for(i=0;i<pt.size();i++){
dfs(pt[i],0);
sum+=f[pt[i]];
}
for(i=0;i<pt.size();i++) sum[i]=mul(sum[i],inv[pt.size()-i]);
ans*=sum;
}
} void solve(){
int i,x,y;
ans[0]=1;
for(i=1;i<=m;i++){
x=e[i<<1].y;
y=e[i<<1^1].y;
if(ok[x]!=ok[y])
ok[x] ? gao(x,y) : gao(y,x);
}
for(i=1;i<=n;i++)
if(ok[i]&&!vis[i]) gao(i,0);
} int main(){ int i,x,y;
n=ri(),m=ri();
for(i=1;i<=m;i++){
x=ri(),y=ri();
deg[x]++,deg[y]++;
e.push2(x,y);
} init();
topu();
solve(); for(i=0;i<=n;i++) printf("%d\n",ans.f[i]); return 0;
}

cf 512D - Fox And Travelling的更多相关文章

  1. Codeforces 512D - Fox And Travelling(树上背包)

    题面传送门 题意: 给出一张无向图,每次你可以选择一个度数 \(\leq 1\) 的点并将其删除. 问对于 \(k=0,1,2,\dots,n\),有多少个删除 \(k\) 个点的序列,答案模 \(1 ...

  2. CF 371B Fox Dividing Cheese[数论]

    B. Fox Dividing Cheese time limit per test 1 second memory limit per test 256 megabytes input standa ...

  3. CF 510b Fox And Two Dots

    Fox Ciel is playing a mobile puzzle game called "Two Dots". The basic levels are played on ...

  4. [CF #290-C] Fox And Names (拓扑排序)

    题目链接:http://codeforces.com/contest/510/problem/C 题目大意:构造一个字母表,使得按照你的字母表能够满足输入的是按照字典序排下来. 递归建图:竖着切下来, ...

  5. cf E. Fox and Card Game

    http://codeforces.com/contest/389/problem/E 题意:给你n个序列,然后两个人x,y,两个人玩游戏,x从序列的前面取,y从序列的后面取,两个人都想自己得到的数的 ...

  6. cf C. Fox and Box Accumulation

    题意:输入一个n,然后输入n个数,问你可以划分多少个序列,序列为:其中一个数为c,在它的前面最多可以有c个数. 思路:先排序,然后对于每一个数逐步的找没有被用过的数,且这个数可以符合条件,然后如果没有 ...

  7. cf B. Fox Dividing Cheese

    http://codeforces.com/contest/371/problem/B #include <cstdio> #include <iostream> #inclu ...

  8. IOI2020 国家集训队作业 泛做

    题号 题目名称 rating 算法 完成情况 CF504E Misha and LCP on Tree CF505E Mr.Kitayuta vs. Bamboos CF506E Mr.Kitayut ...

  9. CF Fox And Names (拓扑排序)

    Fox And Names time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

随机推荐

  1. Python 一行代码输出心形图案

    Python3 >>> print('\n'.join([''.join([('Love'[(x-y)%4]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0. ...

  2. Sum All Primes-freecodecamp算法题目

    Sum All Primes 1.要求 求小于等于给定数值的质数之和. 只有 1 和它本身两个约数的数叫质数.例如,2 是质数,因为它只能被 1 和 2 整除.1 不是质数,因为它只能被自身整除. 2 ...

  3. php v8js

    本文整理自大神 Corz 1.php56 /datas/soft/php56/bin/php -v PHP (cli) #https://blog.csdn.net/lzm198707/article ...

  4. 【104】Maven3.5.0结合eclipse使用,提示Lambda expressions are allowed only at source level 1.8 or above错误的解决方法

    错误重现 我的机器上安装了 maven 3.5.0,在 eclipse 中创建 maven 项目.pom.xml配置如下: <project xmlns="http://maven.a ...

  5. 20190103(GIL,池,阻塞,同步异步)

    GIL锁 什么是GIL GIL全局解释器锁,是防止多个线程在同一时间同时执行的.CPython解释器特有的一种互斥锁. 每一个py文件都会有自己的解释器,也就是说不同py文件的GIL都是独立的, ps ...

  6. Gender Equality in the Workplace【职场上的性别平等】

    Gender Equality in the Workplace A new batch of young women - members of the so-called Millennial ge ...

  7. linux系统下单节点hadoop2的配置

    Jdk安装: jdk-7u45-linux-x64.gz cp jdk-7u45-linux-x64.gz /usr/java/ cd /usr/java/ tar -zxvf jdk-7u45-li ...

  8. error LNK2001: unresolved external symbol ___CxxFrameHandler3

    Q:  VS2005编译的静态库, 在vc++6.0中连接出现错误 error LNK2001: unresolved external symbol ___CxxFrameHandler3 A:   ...

  9. MFC定时关机程序的实现1

    写个定时关机程序自用,界面简单实用,最终界面如下 第一步,新建一个MFC对话框应用程序,拖几个控件过来, 界面如下: 然后给下拉列表框,复选按钮绑定变量,以方便进行操作. CComboBox m_co ...

  10. 学习python3之路的第一个小代码-----------9*9乘法表

    这个编写的简单,用两个循环迭代就行.下面就是我写的编码以及输出的结果 1 #!/usr/bin/env python 2 # encoding: utf-8 3 4 i = 1 5 6 while i ...