bzoj 4784: [Zjoi2017]仙人掌【tarjan+树形dp】
其实挺简单的但是没想出来…………
首先判断无解情况,即,一开始的图就不是仙人掌,使用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<iostream>
#include<cstdio>
#include<cstring>
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]<dfn[u])
{
if(flag)
{
fl=0;
return;
}
flag=1;
}
}
else
{
low[u]=min(low[u],dfn[e[i].to]);
if(dfn[e[i].to]<dfn[u])
{
if(flag)
{
fl=0;
return;
}
flag=1;
}
}
}
if(dfn[u]==low[u])
{
while(1)
{
bl[s[top--]]=u;
if(s[top+1]==u)
break;
}
}
}
void dp(int u,int fa)
{//cout<<u<<endl;
v[u]=1,f[u]=1;g[u]=0;
int sum=0;
for(int i=h[u];i;i=e[i].ne)
if(bl[u]!=bl[e[i].to]&&e[i].to!=fa)
{
dp(e[i].to,u);
f[u]=1ll*f[u]*g[e[i].to]%mod;
sum++;
}
g[u]=(1ll*f[u]*w[sum]%mod+1ll*f[u]*w[sum-1]%mod*sum%mod)%mod;
f[u]=1ll*f[u]*w[sum]%mod;
}
int main()
{
T=read();
w[0]=1,w[1]=1,w[2]=2;
for(int i=3;i<=500000;i++)
w[i]=(w[i-1]+1ll*w[i-2]*(i-1)%mod)%mod;
while(T--)
{
cnt=0;ans=1;tot=0;fl=1;top=0;
n=read(),m=read();
for(int i=1;i<=n;i++)//比memset快5倍!!
v[i]=0,h[i]=0,bl[i]=0,dfn[i]=0;
for(int i=1;i<=m;i++)
{
int u=read(),y=read();
add(u,y);add(y,u);
}
tarjan(1,0);//cout<<"OK"<<endl;
if(!fl)
{
puts("0");
continue;
}
for(int i=1;i<=n;i++)
if(!v[i])
{
dp(i,0);
ans=ans*f[i]%mod;
}
printf("%lld\n",ans);
}
return 0;
}
bzoj 4784: [Zjoi2017]仙人掌【tarjan+树形dp】的更多相关文章
- Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
原文链接https://www.cnblogs.com/zhouzhendong/p/CF980F.html 题目传送门 - CF980F 题意 给定一个 $n$ 个节点 $m$ 条长为 $1$ 的边 ...
- LOJ2250 [ZJOI2017] 仙人掌【树形DP】【DFS树】
题目分析: 不难注意到仙人掌边可以删掉.在森林中考虑树形DP. 题目中说边不能重复,但我们可以在结束后没覆盖的边覆盖一个重复边,不改变方案数. 接着将所有的边接到当前点,然后每两个方案可以任意拼接.然 ...
- BZOJ4784 ZJOI2017仙人掌(树形dp+dfs树)
首先考虑是棵树的话怎么做.可以发现相当于在树上选择一些长度>=2的路径使其没有交,同时也就相当于用一些没有交的路径覆盖整棵树. 那么设f[i]为覆盖i子树的方案数.转移时考虑包含根的路径.注意到 ...
- [BZOJ 4033] [HAOI2015] T1 【树形DP】
题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...
- [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)
[BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...
- bzoj 2427 软件安装 - Tarjan - 树形动态规划
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- Tarjan+树形DP【洛谷P2515】[HAOI2010]软件安装
[洛谷P2515][HAOI2010]软件安装 题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得 ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- BZOJ 2435 道路修建 NOI2011 树形DP
一看到这道题觉得很水,打了递归树形DP后RE了一组,后来发现必须非递归(BFS) 递归版本84分: #include<cstdio> #include<cstring> #in ...
随机推荐
- 《gis空间分析及应用案例解析》培训总结
<gis空间分析及应用案例解析>培训总结 来源:常德水情 作者:唐校准 发布日期:2014-01-02 2013年12月2630日由中国科学院计算技术研究所教育中心组织的< ...
- Defcon 23最新开源工具NetRipper代码分析与利用
0×01 研究背景 在分析了俄罗斯人被曝光的几个银行木马的源码后,发现其大多均存在通过劫持浏览器数据包来获取用户个人信息的模块,通过截获浏览器内存中加密前或解密后的数据包来得到数据包的明文数据.在De ...
- ubuntu12.04安装搜狗输入法记录
http://blog.sina.com.cn/s/blog_66fa66650101akip.html 看了http://www.cnblogs.com/A-Song/archive/2013/04 ...
- javascript array-like object
http://www.nfriedly.com/techblog/2009/06/advanced-javascript-objects-arrays-and-array-like-objects/ ...
- uva live 12846 A Daisy Puzzle Game
假设下一个状态有必败.那么此时状态一定是必胜,否则此时状态一定是必败 状压DP #include<iostream> #include<map> #include<str ...
- 使用MySQL Workbench进行数据库设计——MySQL Workbench用法总结
转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/48318877 本文出自[我是干勾鱼的博客] 1 简单介绍 MySQL Workb ...
- Oracle APEX 4.2安装和配置
A standard Oracle 11.2.0.3 database installation comes bundled with Application Express (APEX) 3.2.1 ...
- FancyCoverFlow
https://github.com/davidschreiber/FancyCoverFlow
- eclipse中导入其它的webproject遇到和解决的问题
注:下面为我从网上搜来的方法.经使用及学习后整理. 学习javaweb有段时间了.对于导入新项目.遇到好多问题.但终于成功了. 错误1:string cannot be resolved to a t ...
- C++手稿:std::string
字符串在非常多编程语言中已经成为基本数据类型,C语言中我们使用char*来手动申请和维护字符串, 在C++中,能够使用std::string来方便地创建和操作字符串. string是一个模板类.它有b ...