P10779 BZOJ4316 小 C 的独立集 (仙人掌DP)
1.数塔2.[洛谷P2014] 选课3.玉蟾宫 (悬线DP)4.MooFest POJ-1990 (树状数组)5.情书密码 (树状数组)6.[SCOI 2009] 迷路 (矩阵快速幂)7.[BZOJ3306] 树8.[NOI2002] 荒岛野人9.SHUFFLE 洗牌 (扩展欧几里得+龟速乘)10.[SDOI2009] Bill的挑战 (状压DP)11.P4168 [Violet] 蒲公英 (莫队的强制在线)12.P3667 [USACO17OPEN] Bovine Genomics G (set容器+二分)13.P7903 兜心の顶(构造)14.[BZOJ2720 Violet 5]列队春游(概率期望+组合数学)15.划分大理石(多重背包)16.P5746 [NOI2002] 机器人M号17.苍与红的试炼(数位DP)18.【唐赛】高一小学期2
19.P10779 BZOJ4316 小 C 的独立集 (仙人掌DP)
20.关于求合法括号子序列个数P10779 BZOJ4316 小 C 的独立集
虽然在圆方树专题中,但我们没有必要把圆方树建出来...
题意
给出一个仙人掌图,求最大独立集
就像是没有上司的舞会超级加倍
没有做过的可以先去康康~
分析
显然树形DP,但是是在仙人掌图上。
至于啥是仙人掌图嘛~
感性的李姐一下就是一棵树塞几个基环且强连通。
引用某dalao的一张图就是:
由于有环,不难想到 Tarjan,所以我们考虑在 Tarjan 的过程中求解。
我们设
当一条边是树边的时候,正常DP。
否则暂时不转移。
当我们做完当前点,发现它是一个环的最顶端的时候,我们需要重新对这个环计算一遍答案。
从这个环的最底端开始往上跳,每次合并一次答案。
维护两个变量
考虑分讨:
-
若最顶端不选
显然最底端选或者不选是没有影响的。然后正常转移,最后把算出来的
直接加给顶点。 -
若顶端选
那么最底下的那个点就一定不能选,直接令
初值为 ,然后正常转移就好了。
没了。
Code
#include<bits/stdc++.h>
#define 我永远喜欢 return
#define 伊蕾娜 0;
using namespace std;
#define int long long
#define rd read()
#define pii pair<int,int>
#define mkp make_pair
#define psb push_back
inline int read(){
int f=1,x=0;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f=(ch=='-'?-1:1);
for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return f*x;
}
const int N=1e5+100;
const int inf=0x7fffffff7fffffff;
int n,m,cnt,f[N][2],fa[N];
vector<int> G[N],T[N*2];
int dfn[N],low[N],num;
void dp(int x,int y){
int g0=0,g1=0,f0=0,f1=0;
for(int i=y;i!=x;i=fa[i]){
g0=f0+f[i][0],g1=f1+f[i][1];
f0=max(g0,g1),f1=g0;
}
f[x][0]+=f0;
f0=0,f1=-inf;
for(int i=y;i!=x;i=fa[i]){
g0=f0+f[i][0],g1=f1+f[i][1];
f0=max(g0,g1),f1=g0;
}
f[x][1]+=f1;
}
void tarjan(int x,int ff){
fa[x]=ff;
low[x]=dfn[x]=++num;
f[x][1]=1;
f[x][0]=0;
for(auto to:G[x]){
if(!dfn[to]){
tarjan(to,x);
low[x]=min(low[x],low[to]);
}else if(to!=ff){
low[x]=min(low[x],dfn[to]);
}
if(low[to]>dfn[x]){
f[x][1]+=f[to][0];
f[x][0]+=max(f[to][0],f[to][1]);
}
}
for(auto to:G[x]){
if(fa[to]!=x&&dfn[x]<dfn[to]){
dp(x,to);
}
}
}
signed main(){
n=rd,m=rd;
for(int i=1;i<=m;i++){
int x=rd,y=rd;
G[x].psb(y);
G[y].psb(x);
}
tarjan(1,0);
printf("%lld",max(f[1][0],f[1][1]));
我永远喜欢 伊蕾娜
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本