题意:求仙人掌图直径。

算法:建出仙人掌圆方树,对于圆点直接做普通的树上DP(忽略方点儿子),方点做环上DP并将值直接赋给父亲。

建图时有一个很好的性质,就是一个方点在邻接表里的点的顺序正好就是从环的根开始的整个环的点的顺序,所以可以直接DP。

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=,inf=;
int n,m,tot,tim,top,u,v;
int dfn[N],low[N],stk[N],f[N][],S[N][]; struct E{
int cnt,h[N],nxt[N<<],to[N<<];
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
}G,G1; void Tarjan(int x,int pre){
dfn[x]=low[x]=++tim; stk[++top]=x;
for (int i=G.h[x],k; i; i=G.nxt[i])
if ((k=G.to[i])!=pre){
if (!dfn[k]){
Tarjan(k,x); low[x]=min(low[x],low[k]);
if (low[k]>dfn[x]) top--,G1.add(x,k);
else if (low[k]==dfn[x]){
tot++; int t;
do{ t=stk[top--]; G1.add(tot,t); } while (t!=k);
G1.add(x,tot); G1.add(tot,x);
}
}
else low[x]=min(low[x],dfn[k]);
}
} void dfs(int x,int fa){ printf("%d\n",x); for (int i=G1.h[x],k; i; i=G1.nxt[i]) if (G1.to[i]!=fa) dfs(G1.to[i],x); } void DP(int x,int fa){
//printf("%d\n",x);
if (x<=n){
f[x][]=; f[x][]=;
for (int i=G1.h[x],k; i; i=G1.nxt[i]){
DP(k=G1.to[i],x);
if (k<=n) f[x][]+=max(f[k][],f[k][]),f[x][]+=f[k][];
}
}else{
for (int i=G1.h[x]; i; i=G1.nxt[i]) if (G1.to[i]!=fa) DP(G1.to[i],x); int top=;
for (int i=G1.h[x],k; i; i=G1.nxt[i])
S[++top][]=f[k=G1.to[i]][],S[top][]=f[k][];
for (int i=top-; i; i--)
S[i][]+=max(S[i+][],S[i+][]),S[i][]+=S[i+][];
f[fa][]=S[][]; top=;
for (int i=G1.h[x],k; i; i=G1.nxt[i])
S[++top][]=f[k=G1.to[i]][],S[top][]=f[k][];
S[top][]=-inf;
for (int i=top-; i; i--)
S[i][]+=max(S[i+][],S[i+][]),S[i][]+=S[i+][];
f[fa][]=S[][];
}
} int main(){
freopen("bzoj4316.in","r",stdin);
freopen("bzoj4316.out","w",stdout);
scanf("%d%d",&n,&m); tot=n;
rep(i,,m) scanf("%d%d",&u,&v),G.add(u,v),G.add(v,u);
Tarjan(,); DP(,); //dfs(1,0);
//rep(i,1,tot) printf("%d %d\n",f[i][0],f[i][1]); puts("");
printf("%d\n",max(f[][],f[][]));
return ;
}

[BZOJ4316]小C的独立集(圆方树DP)的更多相关文章

  1. [BZOJ2125]最短路(圆方树DP)

    题意:仙人掌图最短路. 算法:圆方树DP,$O(n\log n+Q\log n)$ 首先建出仙人掌圆方树(与点双圆方树的区别在于直接连割边,也就是存在圆圆边),然后考虑点u-v的最短路径,显然就是:在 ...

  2. BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus). 所谓简单回路就是指在图上不重复经过任何一个顶点 ...

  3. [BZOJ5463][APIO2018]铁人两项(圆方树DP)

    题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...

  4. [HDU5739]Fantasia(圆方树DP)

    题意:给一张无向点带有权无向图.定义连通图的权值为图中各点权的乘积,图的权值为其包含的各连通图的权和.设z_i为删除i点后图的权值,求$S = (\sum\limits_{i=1}^{n}i\cdot ...

  5. 洛谷4630APIO2018铁人两项(圆方树+dp)

    QWQ神仙题啊(据说是今年第一次出现圆方树的地方) 首先根据题目,我们就是求对于每一个路径\((s,t)\)他的贡献就是两个点之间的点数,但是图上问题我并没有办法很好的解决... 这时候考虑圆方树,我 ...

  6. bzoj4316小C的独立集(dfs树/仙人掌+DP)

    本题有两种写法,dfs树上DP和仙人掌DP. 先考虑dfs树DP. 什么是dfs树?其实是对于一棵仙人掌,dfs后形成生成树,找出非树边(即返祖边),然后dfs后每条返祖边+其所覆盖的链构成了一个环( ...

  7. 2019.02.07 bzoj4316: 小C的独立集(仙人掌+树形dp)

    传送门 题意:给出一个仙人掌森林求其最大独立集. 思路:如果没有环可以用经典的树形dpdpdp解决. fi,0/1f_{i,0/1}fi,0/1​表示第iii个点不选/选的最大独立集. 然后fi,0+ ...

  8. 图论杂项细节梳理&模板(虚树,圆方树,仙人掌,欧拉路径,还有。。。)

    orzYCB 虚树 %自为风月马前卒巨佬% 用于优化一类树形DP问题. 当状态转移只和树中的某些关键点有关的时候,我们把这些点和它们两两之间的LCA弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...

  9. 仙人掌 && 圆方树 && 虚树 总结

    仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...

随机推荐

  1. 深入探讨Android异步精髓Handler

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  2. 论文讨论&&思考《Deformable Convolutional Networks》

    这篇论文真是让我又爱又恨,可以说是我看过的最认真也是最多次的几篇paper之一了,首先deformable conv的思想我觉得非常好,通过end-to-end的思想来做这件事也是极其的make se ...

  3. ListView使用--文章集锦

    详解ListView加载网络图片的优化,让你轻松掌握! ListView具有多种item布局--实现微信对话列 关注公众号,分享干货,讨论技术

  4. Ubuntu gnome 16.04下的一些个人配置

    虽说并没有改什么,但还是花了我很长时间去搞明白…… 最开始要看下这里,调下比如系统时间等东西 UPD:安装时千万不要对主目录进行加密 1.登录前调整一下触控板和打开小键盘 先打开/etc/gdm3/I ...

  5. 在Servlet中出现一个输出中文乱码的问题

     添加:reqeust.setCharacterEncoding("utf-8");

  6. bzoj1833: [ZJOI2010]count 数字计数 && codevs1359 数字计数

    bzoj1833 codevs1359 这道题也是道数位dp 因为0有前导0这一说卡了很久 最后发现用所有位数减1~9的位数就okay.....orzczl大爷 其他就跟51nod那道统计1出现次数一 ...

  7. codevs 1018 [noip 2000 提高] 单词接龙

    题目链接:http://codevs.cn/problem/1018/ 题目描述 Description 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...

  8. 3.flume安装以及环境配置

    1.安装jdk 我这里已经安装过了,这里就不演示了 2.安装flume 安装cdh版本的,http://archive.cloudera.com/cdh5/cdh/5/ 安装完毕之后,配置环境变量. ...

  9. 【C语言】++(a++)的写法是错的

    http://bbs.csdn.net/topics/390764053 a++得到的是一个右值,++操作需要的是一个左值. ------------------------------------- ...

  10. Selenium2+python自动化56-unittest之断言(assert)【转载】

    前言 在测试用例中,执行完测试用例后,最后一步是判断测试结果是pass还是fail,自动化测试脚本里面一般把这种生成测试结果的方法称为断言(assert). 用unittest组件测试用例的时候,断言 ...