博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 4784: [Zjoi2017]仙人掌【tarjan+树形dp】
阅读量:5299 次
发布时间:2019-06-14

本文共 1278 字,大约阅读时间需要 4 分钟。

其实挺简单的但是没想出来…………

首先判断无解情况,即,一开始的图就不是仙人掌,使用tarjan判断如果一个点dfs下去有超过一个点比他早,则说明存在非简单环。
然后考虑dp,显然原图中已经属于某个简单环的边就是没用的,tarjan缩点之后删掉两个端点在一个强连通分量中的边。(无向图的tarjan要记录father防止往回走,instack数组不需要了。
现在图变成了一个森林。
然后设sum为某个点的子树个数,w[i]为i棵子树相互连成环的方案数,w[i]=w[i-1]+w[i-2]*(i-1);g[i]为第i个点(i不是根)的方案数,g[u]=f[u]*w[sum]+f[u]*w[sum-1]*sum;f[i]为第i个点(i是根)的方案数f[u]=f[u]*w[sum]
依次树形dp,把答案乘起来即可。

#include
#include
#include
using namespace std;const int N=500005,mod=998244353;int T,n,m,h[N],cnt,f[N],w[N],g[N],dfn[N],tot,low[N],bl[N],col,s[N],top;bool v[N],fl;long long ans;struct qwe{ int ne,to;}e[N*10];int read(){ int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f;}void add(int u,int v){ cnt++; e[cnt].ne=h[u]; e[cnt].to=v; h[u]=cnt;}void tarjan(int u,int fa) { dfn[u]=low[u]=++tot; s[++top]=u; bool flag=0; for(int i=h[u];i;i=e[i].ne) if(e[i].to!=fa) { if(!dfn[e[i].to]) { tarjan(e[i].to,u); low[u]=min(low[u],low[e[i].to]); if(low[e[i].to]

转载于:https://www.cnblogs.com/lokiii/p/8505970.html

你可能感兴趣的文章
常用的分析方法有哪些?
查看>>
Excel-图表制作
查看>>
面对问题,如何去分析?(流失问题)
查看>>
Excel 文本函数
查看>>
电商数据分析总结
查看>>
Excel-信息函数&数组公式
查看>>
Excel-基本操作
查看>>
面对问题,如何去分析?(分析套路)
查看>>
Excel-逻辑函数
查看>>
面对问题,如何去分析?(日报问题)
查看>>
数据分析-业务知识
查看>>
求职秘籍-简历制作?
查看>>
用配置文件里面的参数值替换yaml模板中的变量值【python】
查看>>
Linux自动输入密码登录用户
查看>>
kvm虚拟机操作相关命令及虚拟机和镜像密码修改
查看>>
全球项目多区域数据同步问题解决方案
查看>>
spring boot jpadata 使用
查看>>
BZOJ1208[HNOI2004]宠物收养场——treap
查看>>
nodejs vs python
查看>>
poj-1410 Intersection
查看>>