【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)
【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)
题面
题解
显然如果原图不是仙人掌就无解。
如果原图是仙人掌,显然就是把环上的边给去掉,变成若干森林连边成为仙人掌的方案数。
那么对于一棵树而言,考虑其变成仙人掌的方案数。
设\(a_i\)表示匹配\(i\)个儿子的方案数,显然转移时\(a_i=a_{i-1}+(i-1)*a_{i-2}\),即考虑新加入的儿子是匹配另外一个儿子还是不管。
设\(f_u\)表示节点\(u\)的子树匹配成仙人掌的方案数,这里要考虑\(x\)到其父亲的边。
那么对于每个点的转移就是考虑其所有儿子的边的匹配问题,显然假设儿子个数为\(d\)的话,那么\(f_u=a_d\prod_{v,(u,v)\in E}f_v\)。
然后这个玩意真的要\(dp\)吗。。。。
就是\(\prod a_{degree_i}\)。所以求求每个点的度数就好了。
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 1000100
#define MOD 998244353
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX<<2];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int n,m,a[MAX],mxn=1;
bool vis[MAX],chk;
int dfn[MAX],low[MAX],G[MAX],gr,tim;
bool ins[MAX];int S[MAX],top;
void init(int n)
{
for(int i=1;i<=n;++i)vis[i]=false,h[i]=dfn[i]=low[i]=G[i]=0;
for(int i=mxn+1;i<=n;++i)a[i]=(a[i-1]+1ll*(i-1)*a[i-2])%MOD;
mxn=max(mxn,n);cnt=1;tim=gr=0;chk=true;
}
void Tarjan(int u,int ff)
{
ins[u]=true;S[++top]=u;dfn[u]=low[u]=++tim;
bool ret=false;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;
if(!dfn[v])
{
Tarjan(v,u),low[u]=min(low[u],low[v]);
if(low[v]<dfn[u])ret?chk=false:ret=true;
}
else if(ins[v])
{
low[u]=min(low[u],dfn[v]);
if(low[v]<dfn[u])ret?chk=false:ret=true;
}
}
if(dfn[u]==low[u])
{
int v;++gr;
do{v=S[top--];ins[v]=false;G[v]=gr;}while(u!=v);
}
}
int ans,size[MAX];
void dfs(int u,int ff)
{
int son=ff!=0;vis[u]=true;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff||G[v]==G[u])continue;
++son;dfs(v,u);
}
ans=1ll*ans*a[son]%MOD;
}
int Work()
{
for(int i=1,u,v;i<=m;++i)u=read(),v=read(),Add(u,v),Add(v,u);
for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(i,0);
if(!chk)return 0;ans=1;
for(int i=1;i<=n;++i)if(!vis[i])dfs(i,0);
return ans;
}
int main()
{
int T=read();a[0]=1;a[1]=1;
while(T--)
{
n=read();m=read();init(n);
printf("%d\n",Work());
}
}
【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)的更多相关文章
- [BZOJ4784][ZJOI2017]仙人掌(树形DP)
4784: [Zjoi2017]仙人掌 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 312 Solved: 181[Submit][Status] ...
- 2019.02.07 bzoj4784: [Zjoi2017]仙人掌(仙人掌+树形dp)
传送门 题意:给一个无向连通图,问给它加边形成仙人掌的方案数. 思路: 先考虑给一棵树加边形成仙人掌的方案数. 这个显然可以做树形dp. fif_ifi表示把iii为根的子树加边形成仙人掌的方案数. ...
- BZOJ4784 ZJOI2017仙人掌(树形dp+dfs树)
首先考虑是棵树的话怎么做.可以发现相当于在树上选择一些长度>=2的路径使其没有交,同时也就相当于用一些没有交的路径覆盖整棵树. 那么设f[i]为覆盖i子树的方案数.转移时考虑包含根的路径.注意到 ...
- bzoj4784 [Zjoi2017]仙人掌
Description 如果一个无自环无重边无向连通图的任意一条边最多属于一个简单环,我们就称之为仙人掌.所谓简单环即不经过重复的结点的环. 现在九条可怜手上有一张无自环无重边的无向连通图,但是她觉得 ...
- 【BZOJ4316】小C的独立集(仙人掌,动态规划)
[BZOJ4316]小C的独立集(仙人掌,动态规划) 题面 BZOJ 题解 除了普通的动态规划以外,这题还可以用仙人掌的做法来做. 这里没有必要把圆方树给建立出来 \(Tarjan\)的本质其实就是一 ...
- 【BZOJ1023】仙人掌图(仙人掌,动态规划)
[BZOJ1023]仙人掌图(仙人掌,动态规划) 题面 BZOJ 求仙人掌的直径(两点之间最短路径最大值) 题解 一开始看错题了,以为是求仙人掌中的最长路径... 后来发现看错题了一下就改过来了.. ...
- UOJ#290. 【ZJOI2017】仙人掌 仙人掌,Tarjan,计数,动态规划,树形dp,递推
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ290.html 题解 真是一道好题! 首先,如果不是仙人掌直接输出 0 . 否则,显然先把环上的边删光. ...
- bzoj 4784: [Zjoi2017]仙人掌【tarjan+树形dp】
其实挺简单的但是没想出来---- 首先判断无解情况,即,一开始的图就不是仙人掌,使用tarjan判断如果一个点dfs下去有超过一个点比他早,则说明存在非简单环. 然后考虑dp,显然原图中已经属于某个简 ...
- uva 11324 The Largest Clique(图论-tarjan,动态规划)
Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...
随机推荐
- django 路由系统,数据库操作
一.修改配置 数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dbname', 'USER': ...
- vue动态class——实现tag的选中状态
vue动态class——实现tag的选中状态 <template> <div class="common-nav"> <div class=" ...
- Java 数据库简单操作类
数据库操作类,将所有连接数据库的配置信息以及基本的CRUD操作封装在一个类里,方便项目里使用,将连接数据库的基本信息放在配置文件 "dbinfo.properties" 中,通过类 ...
- 前K个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...
- Spring boot + mybatis + orcale实战(干货)
废话少说,直接上步骤: 第一步:安装好IDEA(此处省略) 第二步:在IDEA新建springboot工程 第三步:在springboot工程的pom.xml添加oracle和mybait依赖 < ...
- checkbox操作判断 Jquery选择器
function checkAll(d){ console.log(d); console.log(d.checked); //注意 这里是d不是$(d) 不是jQuery对象 if(d.checke ...
- python 列表、元组、字典
一.列表 [ ] 如下的列子都可以成为列表,c=[1,2,3,4,5,6],d=["abc", "张三",“李四”],e=[1,2,3,"abc&qu ...
- ERP系统的问题
1.业务统计报表导出超时 2.库存统计相关接口查询容易导致慢查询,而且慢查询出现在主库上
- Lodop打印控件 超文本自动分页
Lodop打印控件打印html超文本,通常传入一个超文本内容可能会超过纸张,如果要拆分每页显示哪些然后手动分页比较麻烦,Lodop中的超文本都有自动分页的特点.自动分页的依据:1.超文本超过设置的打印 ...
- Modbus CRC 16 (C#)
算法 1.预置一个值为 0xFFFF 的 16 位寄存器,此寄存器为 CRC 寄存器. 2.把第 1 个 8 位二进制数据(即通信消息帧的第 1 个字节)与 16 位的 CRC 寄存器相异或,异或的结 ...