题目大意

定义仙人球为一个无自环重边的、每个点最多属于一个简单环的无向连通图
现在给定一个nn个点mm条边的仙人球,你要从其中选出至多KK个,使得这些点满足能在不经过其它没被选择的点的情况下互相连通。不能不选点。
求出方案数模109+710^9+7。

1≤n≤5×103,1≤K≤min(n,100)1\le n\le5\times10^3,1\le K\le\min(n,100)


题目分析

可以发现仙人球就是一堆环形成一个树形结构(孤立的单点也可以看做环)。
那么我们考虑使用动态规划。
设fi,jf_{i,j}表示做到第ii个环,以这个环为根的子仙人球总共选择了jj个节点,并且当前环的深度最小的点一定选择了的方案数。
考虑将环上每个点为根的子仙人球的信息放到点上,令hi,jh_{i,j}表示当前环第ii个点为根的子仙人球(如下图颜色圈中的各个块)选择了jj个节点的方案数。

hih_{i}可以很方便地由第ii个点的所有儿子的ff推出。
那么现在考虑知道了hih_{i}怎么求出ff。
现在我们相当于在一个环上有若干个关键点,第ii个关键点选择jj个点有hi,jh_{i,j}种方案。求整个环从11号点(环深度最小的点即顶点)开始向两边若干连续关键点选出点的方案。
我们令F0,i,jF_{0,i,j}表示从点11向后扩展到点ii,每个关键点都至少选出一个点,总共选出jj个点的方案数。F1,i,jF_{1,i,j}则是从最后一个点向前扩展到点ii,其它类似。

F0/1,i,jF_{0/1,i,j}通过hi,jh_{i,j}易得。
令tottot为环上关键点个数。我们得出这个以后,就可以通过

fx,j=F0,tot,j+∑i=1totF0,i,k∑l=i+2totF1,l,j−k

f_{x,j}=F_{0,tot,j}+\sum_{i=1}^{tot}F_{0,i,k}\sum_{l=i+2}^{tot}F_{1,l,j-k}
来计算 ff的值,后面那个sigma显然可以使用后缀和维护,而为什么是从i+2i+2开始枚举呢?因为如果我们算上 i+1i+1,那就会把整个环的关键点都有点选的情况计算上 tottot次。而式子前面那个 F0,tot,jF_{0,tot,j}就是把这种情况一次性算了。
那么知道了 ff,我们怎么统计答案呢?
设gi,jg_{i,j}表示做到第 ii个环,以这个环为根的子仙人球总共选择了jj个节点,并且当前环至少选了一个点的方案数。我们求答案时把所有 gi,jg_{i,j}加起来就行了。
怎么计算 gg呢?gg相当于在环上的连续一段关键点中选点。我们分两种情况讨论:一种是这连续的一段没有跨过第一个点和最后一个点的连边,另一种是这连续的一段跨过了第一个点和最后一个点的连边。
我们令 Gi,jG_{i,j}表示环上第 ii个关键点向前连续选点,选了jj个的方案数,方程和 FF是有点类似的。那么所有的Gi,jG_{i,j}求和就是第一种情况。
至于第二种情况呢?可以发现它其实就是从第一个点和最后一个点分别向两边延伸,和 ff的计算过程是差不多的,唯一的不同就是从最后一个点延伸那边不能一个点都不选,不然就会算重。
计算过程中不需要显式地弄gg出来,我只是为了统计方便弄了这个辅助变量。
所有过程都是 O(nK2)\mathrm O(nK^2)的。


代码实现

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cctype>
#include <stack>using namespace std;int read()
{int x=0,f=1;char ch=getchar();while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar();while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();return x*f;
}const int P=1000000007;
const int N=5050;
const int M=N<<1;
const int E=M<<1;
const int MAXK=105;int f[N][MAXK],g[N][MAXK],h[N][MAXK],F[2][N][MAXK],G[N][MAXK],sum[MAXK];
int last[N],bel[N],DFN[N],low[N];
int tov[E],rev[E],nxt[E];
stack<int> st;
int cir[N][N];
int idx,cnt,n,m,tot,K,ans,root;void insert(int x,int y,int r){tov[++tot]=y,rev[tot]=tot+r,nxt[tot]=last[x],last[x]=tot;}void tarjan(int x,int fe)
{DFN[x]=low[x]=++idx,st.push(x);for (int i=last[x],y;i;i=nxt[i])if (i!=fe)if (!DFN[y=tov[i]]) tarjan(y,rev[i]),low[x]=min(low[x],low[y]);else low[x]=min(low[x],DFN[y]);if (DFN[x]==low[x]){++cnt;int y;do{y=st.top(),cir[bel[y]=cnt][++cir[cnt][0]]=y,st.pop();}while (x!=y);for (int i=1;i*2<=cir[cnt][0];i++) swap(cir[cnt][i],cir[cnt][cir[cnt][0]+1-i]);if (x==1) root=cnt;}
}void dp(int cid,int fa)
{int son=cir[cid][0];for (int i,x,y,j=1;j<=son;j++)for (i=last[x=cir[cid][j]];i;i=nxt[i])if ((y=tov[i])!=fa&&bel[y]!=cid) dp(bel[y],x);for (int i,x,y,u,j=1;j<=son;j++){for (i=0;i<=K;i++) h[j][i]=0;h[j][1]=1;for (i=last[x=cir[cid][j]];i;i=nxt[i])if ((y=tov[i])!=fa&&(u=bel[y])!=cid)for (int k=K;k>=1;k--)for (int l=1;l<=K-k;l++)(h[j][k+l]+=1ll*h[j][k]*f[u][l]%P)%=P;}/*calculate G*/for (int i=1;i<=K;i++) G[1][i]=h[1][i];for (int i=2;i<=son;i++)for (int j=K;j>=1;j--){G[i][j]=h[i][j];for (int k=1;k<=K-j;k++) (G[i][j+k]+=1ll*G[i-1][j]*h[i][k]%P)%=P;}for (int i=1;i<=son;i++)for (int j=1;j<=K;j++)(g[cid][j]+=G[i][j])%=P;/*calculate F*/for (int i=1;i<=K;i++) F[0][1][i]=h[1][i];for (int i=2;i<=son;i++)for (int j=K;j>=1;j--){F[0][i][j]=0;for (int k=1;k<=K-j;k++) (F[0][i][j+k]+=1ll*F[0][i-1][j]*h[i][k]%P)%=P;}for (int i=1;i<=K;i++) F[1][son][i]=h[son][i];for (int i=son-1;i>=1;i--)for (int j=K;j>=1;j--){F[1][i][j]=0;for (int k=1;k<=K-j;k++) (F[1][i][j+k]+=1ll*F[1][i+1][j]*h[i][k]%P)%=P;}for (int i=0;i<=K;i++) sum[i]=0;for (int i=1;i<=K;i++) f[cid][i]=F[1][1][i];sum[0]=1;for (int i=son-1;i>=1;i--){for (int j=1;j<=K;j++)for (int k=0;k<=K-j;k++){(f[cid][j+k]+=1ll*F[0][i][j]*sum[k]%P)%=P;if (k) (g[cid][j+k]+=1ll*F[0][i][j]*sum[k]%P)%=P;}for (int j=1;j<=K;j++) (sum[j]+=F[1][i+1][j])%=P;}
}void calc()
{ans=0;for (int i=1;i<=cnt;i++)for (int j=1;j<=K;j++)(ans+=g[i][j])%=P;
}int main()
{freopen("cactus.in","r",stdin),freopen("cactus.out","w",stdout);n=read(),m=read(),K=read();for (int i=1,x,y;i<=m;i++) x=read(),y=read(),insert(x,y,1),insert(y,x,-1);tarjan(1,0),dp(root,0),calc();printf("%d\n",ans);fclose(stdin),fclose(stdout);return 0;
}

[JZOJ4949]仙人球相关推荐

  1. HDU2153 仙人球的残影【数学计算+水题】

    仙人球的残影 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  2. 仙人球模型matlab,3dmax软件如何制作带刺的仙人球模型?

    你知道用3dmax软件如何制作带刺的仙人球模型?本文小编将为大家带来用3DMAX制作仙人球快速建模的方法,有需要的小伙伴们快和小编一起来看看3dmax软件建模带刺的仙人球模型的详细步骤与教程吧! 3d ...

  3. HDU - 2153 仙人球的残影

    OJ地址:https://vjudge.net/problem/HDU-2153 在美丽的HDU,有一名大三的同学,他的速度是众所周知的,跑100米仅仅用了2秒47,在他跑步过程中会留下残影的哎,大家 ...

  4. 【模拟】仙人球的残影

    描述 在美丽的TZC,有一名大三的同学,他的速度是众所周知的,跑100米仅仅用了2秒47,在他跑步过程中会留下残影的哎,大家很想知道他是谁了吧,他叫仙人球,既然名字这样了,于是他的思想是单一的,他总是 ...

  5. 仙人球模型matlab,数字人C4D建模课堂之十六:仙人球建模

    目的: 有上面几节课的知识做基础,这节课简要谈谈仙人球的制作思路,并对难点做解释.感兴趣的朋友可以自己尝试制作,有问题,到C4D吧询问,共同研究. 1.如何制作仙人球体 因为还要细分,所以尽量减少分段 ...

  6. 花卉世界大观园和杂技之游

    最近的周末一直在忙,总算抽出来了一个周末来,我就计划着和家里人出去玩玩,想了几个路线,最后定格为早上去花卉世界大观园,南四环,离我住的地方不远,下午计划去朝阳剧院看杂技. 我们赶了个大早进去,就是怕中 ...

  7. OSChina 周二乱弹 —— 最要命的编程语言?

    2019独角兽企业重金招聘Python工程师标准>>> 昨天是周一,没有加班的盆友摸摸你的良心问问,你是不是个合格的程序员? 房间干净有条理的人,找起东西来都像程序员,设好运算模式, ...

  8. 怎么将算法改成程序_多肉烂根怎么办?将土培改成水培,长势好,叶子变得更水灵...

    导语:养多肉的人多但要知道它最害怕就是用太多的水,会让它出现烂根一烂根就会让它直接死掉,每次在给它浇水时都没有一个数也让人担心不已.其实我们还可以把它直接放在水里养殖,不仅长得好还不会烂根,长势好,叶 ...

  9. 问题战略[置顶] 十八年开发经验分享(四)问题解决篇(下)

    最近一直在研究问题战略之类的问题,下午正好有机会和大家分享一下. 关于本系列文字的源来,衷初和内容定位可以考参第一篇的头开部份,链接址地如下: http://blog.csdn.net/binaryt ...

  10. TensorFlow的新生!

    点击"小詹学Python",选择"置顶"公众号 重磅干货,第一时间送达 本文转载自机器之心 TensorFlow 2.0 带来了大量改变.谷歌工程师 Cassi ...

最新文章

  1. Nginx源码分析-内存池
  2. 随便说说---java初级学习路线
  3. Halcon基于形状的几何定位函数说明
  4. 剑指offer(C++)-JZ55:二叉树的深度(数据结构-树)
  5. JAVA浮点数浮点数转换成人民币读法
  6. 应用程式中夜间模式的Android DayNight主题
  7. eclipse mac oracle数据库,Eclipse连接Oracle数据库的具体步骤
  8. java编程环境_java开发环境
  9. CMake 编译静态库和动态库
  10. 解决WIN10家庭版无法远程桌面连接的问题
  11. 用ReadyBoost提高Windows 7系统性能
  12. 用echarts绘制瀑布图
  13. ES文件浏览器(清理垃圾神器, 强大网盘管理功能, 强大文件分析能力)
  14. 强大到爆的代码阅读工具understand
  15. PS作业 不一样的我
  16. 大学生前端,毕业面试知道这几点,offter拿到手软
  17. 阿里云计算巢软件免费试用中心正式上线,企业用户可免费试用1个月
  18. 台式计算机选购,电脑什么配置好 教你如何选购一台好的台式电脑
  19. Activiti 流程部署方式 activi 动态部署(高级源码篇)
  20. 爱乐乐iLELE®益生菌新品上市由妈咪爱研究中心出品

热门文章

  1. 不修改vender文件夹,重写laravel注册登录功能
  2. 我用Python分析了1500家电商的销售数据,竟发现了进口车厘子的秘密
  3. 计算机专用英语词汇1500词
  4. 《视觉slam十四讲》第3讲课后习题
  5. 大数据工程师面临哪些行业机遇与挑战?
  6. COIL:结合稠密检索和词汇匹配的更高效检索模型
  7. SPJ数据库—初识sql语句(02)(注释版)
  8. Cannot allocate memory
  9. Q4营收突破20亿且连续四个季度盈利斗鱼驶入“后直播时代”快车道
  10. java for循环打印平行四边形,正三角形,菱形和空心菱形