BZOJ 4316 小C的独立集 仙人掌DP
2015-10-30 16:48
295 查看
题目大意:给定一棵仙人掌,求最大点独立集
老办法,每个环新建一个点,连接环上所有点,然后把环上边都拆掉,就变成了一棵树
然后跑树形DP,对于一个点如果是普通节点就正常DP,如果是环上节点参考BZOJ1040
老办法,每个环新建一个点,连接环上所有点,然后把环上边都拆掉,就变成了一棵树
然后跑树形DP,对于一个点如果是普通节点就正常DP,如果是环上节点参考BZOJ1040
#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 120100 using namespace std; int n,m; namespace Tree{ int n; struct abcd{ int to,next; }table[M]; int head[M],tot=1; int f[M][2]; void Add(int x,int y) { table[++tot].to=y; table[tot].next=head[x]; head[x]=tot; } void Tree_DP(int x,int from) { int i; if(x<=::n) { f[x][0]=0;f[x][1]=1; for(i=head[x];i;i=table[i].next) if(table[i].to!=from) { Tree_DP(table[i].to,x); if(table[i].to>::n) continue; f[x][0]+=max(f[table[i].to][0],f[table[i].to][1]); f[x][1]+=f[table[i].to][0]; } } else { static int g[M][2];int top=0; for(i=head[x];i;i=table[i].next) if(table[i].to!=from) Tree_DP(table[i].to,x); for(i=head[x];i;i=table[i].next) { g[++top][0]=f[table[i].to][0]; g[ top][1]=f[table[i].to][1]; } for(i=top-1;i;i--) { g[i][0]+=max(g[i+1][0],g[i+1][1]); g[i][1]+=g[i+1][0]; } f[from][0]=g[1][0]; for(i=1;i<top;i++) { g[i][0]-=max(g[i+1][0],g[i+1][1]); g[i][1]-=g[i+1][0]; } g[top][1]=0xefefefef; for(i=top-1;i;i--) { g[i][0]+=max(g[i+1][0],g[i+1][1]); g[i][1]+=g[i+1][0]; } f[from][1]=g[1][1]; } } } namespace Cactus{ struct abcd{ int to,next; }table[M]; int head[M],tot=1; int fa[M],dfn[M],T; bool on_ring[M]; void Add(int x,int y) { table[++tot].to=y; table[tot].next=head[x]; head[x]=tot; } void DFS(int x,int from) { int i; dfn[x]=++T; for(i=head[x];i;i=table[i].next) if(i^from^1) { if(!dfn[table[i].to]) { fa[table[i].to]=x; on_ring[x]=false; DFS(table[i].to,i); if(!on_ring[x]) { Tree::Add(x,table[i].to); Tree::Add(table[i].to,x); } } else { if(dfn[table[i].to]>dfn[x]) continue; int temp=x;++Tree::n; while(1) { Tree::Add(Tree::n,temp); Tree::Add(temp,Tree::n); on_ring[temp]=true; if(temp==table[i].to) break; temp=fa[temp]; } } } } } int main() { int i,x,y; cin>>n>>m;Tree::n=n; for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); Cactus::Add(x,y); Cactus::Add(y,x); } Cactus::DFS(1,0); Tree::Tree_DP(1,0); cout<<max(Tree::f[1][0],Tree::f[1][1])<<endl; }
相关文章推荐
- BZOJ3275 Number (最小割)
- [bzoj1003] [ZJOI2006]物流运输trans
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- [BZOJ2038][2009国家集训队][莫队][分块]小z的袜子
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- [BZOJ2300][HAOI2011][动态凸包]防线修建
- [BZOJ1045][HAOI2008][贪心]糖果传递
- [BZOJ2539][CTSC2000][KM]丘比特的烦恼
- [BZOJ1004][HNOI2008][Burnside引理][DP]Cards
- [BZOJ1202][HNOI2005][并查集]狡猾的商人
- [BZOJ1179][APIO2009][Tarjan][拓扑排序][递推]Atm
- [BZOJ1095][ZJOI2007][线段树]Hide捉迷藏
- [BZOJ1089][SCOI2003][递推][高精度]严格n元树
- [BZOJ1096][ZJOI2007][DP][斜率优化]仓库建设
- [BZOJ1071][SCOI2007][堆]组队
- [BZOJ1499][NOI2005][DP+优化]瑰丽华尔兹
- [BZOJ1266][AHOI2006][最短路][最小割]上学路线