【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 ...
随机推荐
- 堆排、python实现堆排
一.堆-完全二叉树 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),是不稳定排序 堆排序中的堆有大顶堆.小顶堆两种.他们都是完 ...
- rbac组件权限按钮,菜单,可拔插
1.通用模板 overflow: auto; //在a和b模板中进行切换 a 模板 :左侧菜单跟随滚动条 b模板 左侧以及上不动 **** <!DOCTYPE html> <h ...
- Python爬虫:爬取人人都是产品经理的数据
爬取内容: 人人都是产品经理首页(www.woshipm.com)左侧[最新文章]下如图样式的文章标题.浏览量和缩略图. 思路: 1. 用BeautifulSoup解析网页 变量名 = Beautif ...
- Ubuntu18.04更新源
一.备份/etc/apt/sources.list文件 cd /etc/apt sudo cp sources.list sources.list.old 二.选择国内常用的源 #阿里源 deb ht ...
- Linux kernel support docker storage driver aufs
How to make docker use aufs in CentOS 7? - Server Faulthttps://serverfault.com/questions/650208/how- ...
- tomcat启动参数
/usr/java/jdk1..0_191-amd64/bin/java -Djava.util.logging.config./conf/logging.properties -Djava.util ...
- VMware虚拟机中常见的问题汇总
在使用虚拟机进行开发工作的时候,经常会遇到各种各样的问题, 总结再次, 防微杜渐 1. wget: unable to resolve host address的解决方法 原因分析: DNS域名解析的 ...
- js数据放入缓存,需要再调用
再贴代码之前先描述下,这个技术应用的场景:一个页面的http请求次数能少点就少,这样大大提高用户体验.所以再一个页面发起一个请求,把所有数据都拿到后储存在缓存里面,你想用的时候再调用出来,这个是非常好 ...
- .Net中EF通用数据层小结
增删改查: using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; u ...
- C++中String类的字符串分割实现
最近笔试,经常遇到需要对字符串进行快速分割的情景,主要是在处理输入的时候,而以前练习算法题或笔试,很多时候不用花啥时间考虑测试用例输入的问题.可是C++标准库里面没有像java的String类中提供的 ...