传送门
题意:给出一个仙人掌森林求其最大独立集。


思路:如果没有环可以用经典的树形 d p dp dp解决。
f i , 0 / 1 f_{i,0/1} fi,0/1​表示第 i i i个点不选/选的最大独立集。
然后 f i , 0 + = m a x { f v , 0 , f v , 1 } , f i , 1 + = f v , 0 f_{i,0}+=max\{f_{v,0},f_{v,1}\},f_{i,1}+=f_{v,0} fi,0​+=max{fv,0​,fv,1​},fi,1​+=fv,0​转移即可。
现在有了环考虑把每个环单独提出来更新一下。
就用个队列把整个环记录下来然后分这个环在原图中 d f s dfs dfs出来的最高点选与不选分别 d p dp dp更新即可。
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans;
}
const int N=5e4+5;
int n,m,ans=0,fa[N],dfn[N],low[N],tot=0,f[N][2],g[N][2],q[N],top;
vector<int>e[N];
inline void solve(int rt,int x){int tmp0=f[rt][0],tmp1=f[rt][1],tmp=x;q[top=1]=x;while(x!=rt)x=fa[x],q[++top]=x;x=tmp;g[x][0]=f[x][0],g[x][1]=-0x3f3f3f3f;for(ri i=2;i<=top;++i){g[q[i]][0]=f[q[i]][0]+max(g[q[i-1]][0],g[q[i-1]][1]);g[q[i]][1]=f[q[i]][1]+g[q[i-1]][0];}tmp1=max(tmp1,g[rt][1]);g[x][0]=f[x][0],g[x][1]=f[x][1];for(ri i=2;i<=top;++i){g[q[i]][0]=f[q[i]][0]+max(g[q[i-1]][0],g[q[i-1]][1]);g[q[i]][1]=f[q[i]][1]+g[q[i-1]][0];}tmp0=max(tmp0,g[rt][0]);f[rt][0]=tmp0,f[rt][1]=tmp1;
}
void tarjan(int p){dfn[p]=low[p]=++tot,f[p][1]=1;for(ri i=0,v;i<e[p].size();++i){if((v=e[p][i])==fa[p])continue;if(!dfn[v])fa[v]=p,tarjan(v),low[p]=min(low[p],low[v]);else low[p]=min(low[p],low[v]);if(dfn[p]<low[v])f[p][0]+=max(f[v][0],f[v][1]),f[p][1]+=f[v][0];}for(ri i=0,v;i<e[p].size();++i)if(fa[v=e[p][i]]!=p&&dfn[p]<dfn[v])solve(p,v);
}
int main(){n=read(),m=read();for(ri i=1,u,v;i<=m;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);for(ri i=1;i<=n;++i)if(!dfn[i])tarjan(i),ans+=max(f[i][0],f[i][1]);cout<<ans;return 0;
}

bzoj4316: 小C的独立集(仙人掌+树形dp)相关推荐

  1. BZOJ 4316: 小C的独立集 仙人掌 + 树形DP

    4316: 小C的独立集 Time Limit: 10 Sec  Memory Limit: 128 MB Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. ...

  2. bzoj4316: 小C的独立集

    bzoj4316: 小C的独立集 链接 bzoj 思路 不是环的边==没有上司的舞会. 其他的,把环拿出来,考虑与深度最小的点u的交界处的点选不选,进行两次dp更新f[u] 代码 #include & ...

  3. 【BZOJ-4316】小C的独立集 仙人掌DP + 最大独立集

    4316: 小C的独立集 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 57  Solved: 41 [Submit][Status][Discus ...

  4. bzoj 4316: 小C的独立集(仙人掌树形DP)

    4316: 小C的独立集 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 682  Solved: 380 [Submit][Status][Disc ...

  5. [BZOJ4784][UOJ290][ZJOI017]仙人掌-树形DP

    仙人掌 Description 如果一个无自环无重边无向连通图的任意一条边最多属于一个简单环,我们就称之为仙人掌.所谓简单环即不经过重复的结点的环. 现在九条可怜手上有一张无自环无重边的无向连通图,但 ...

  6. 2018.09.01 独立集(树形dp)

    描述 给定一颗树(边权为1),选取一个节点子集,使得该集合中任意两个节点之间的距离都大于K.求这个集合节点最多是多少 输入 第一行是两个整数N,K 接下来是N-1行,每行2个整数x,y,表示x与y有一 ...

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

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

  8. BZOJ4316 小C的独立集 【仙人掌】

    题目 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使取出的点尽量多. ...

  9. P3698-[CQOI2017]小Q的棋盘【树形dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P3698 题目大意 nnn个点的树,求从111出发走kkk步最多能到多少个节点.(重复走不算) 解题思路 做法与树形 ...

最新文章

  1. 京东到家甩包袱给达达 路走错了合并也没
  2. 谷歌又买算法送手机了,最新方法让背景虚化细节到头发丝,真有单反的感觉了...
  3. 三层登录VB.NET实现
  4. python怎么保存文件代码_Python文件读写保存操作的实现代码
  5. R语言与Shapiro正态性检验
  6. 利用C++实现哈夫曼算法
  7. 50Hz工频干扰消除
  8. CMake使用总结,不断更新
  9. Python:threading(多线程操作)(转载)
  10. Vue项目整体添加加载中Loading页面
  11. 2020年7月的光立方包含程序和PCB文件
  12. 使用晨曦记账本记账,将账目明细导出excel表格上
  13. 使用java 实现 word 转换成图片
  14. HttpWatch软件介绍与基本使用
  15. 服务器怎么组装,如何组装一台服务器?(最好标明下什么类型的)
  16. Excel 导入Access 不能找到表达式中引用的字段的解决方案
  17. 【第十章 线性代数之 特征向量与特征值】3Blue1Brown
  18. mac打不开txt文件,出现“文本编码“中文 (GB 18030)”不适用。”的解决办法
  19. mysql zimbra_记一次zimbra服务器故障导致mysql起不来问题
  20. c语言编程实习,c语言编程实习心得

热门文章

  1. 有道云笔记网页剪报登录不上,反复登录问题
  2. 做c语言时经常遇到的错误,C语言新人常见问题与错误
  3. MATLAB实现随机数方法合集
  4. 深圳大学算法实验总结2021
  5. IPv6:配置Docker支持IPv6
  6. 金山变身网游商上市 民族软件业何其尴尬(转)
  7. sequelize参考
  8. C++编写的QQ木马源代码
  9. 微信公众平台后台接入简介
  10. php调用联通短信接口实例,php通过http调用验证码短信接口源码