【题目链接】
  http://www.lydsy.com/JudgeOnline/problem.php?id=1023
【题解】
  仙人掌入门题,拿圆方树练练手。
  圆方树就是把一个环建一个新方点,然后向每个在环上的点连边,
  接下来就很方便了,用dp的方式求出直径(以这个点为子树的最大直径),在遇到方点时,在环上转两圈。
  复杂度 O( m+n m + n m+n)
  tips:vector用起来很爽

/* --------------user Vanisherproblem bzoj-1023
----------------*/
# include <bits/stdc++.h>
# define    N       500010
using namespace std;
struct node{int data,vote;
};
vector <node> e[N];
int use[N],low[N],dfn[N],ti,st[N],top,num,f[N],ans,h[N],po[N],n,m,su[N],sv[N],len,tag[N],place,fx;
int read(){int tmp=0, fh=1; char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar(); }return tmp*fh;
}
void build(int u, int v, int w){e[u].push_back((node){v,w});e[v].push_back((node){u,w});
}
void tarjan(int x, int fa){use[x]=true; low[x]=dfn[x]=++ti; for (int ed=1; ed<e[x].size(); ed++){if (dfn[x]<dfn[e[x][ed].data]||e[x][ed].data==fa) continue;st[++top]=x;if (use[e[x][ed].data]==false) {tarjan(e[x][ed].data,x);if (st[top]==x){su[++place]=x, sv[place]=e[x][ed].data;top--;}}else {int to=e[x][ed].data;e[++num].push_back((node){0,0});int s=top;while (st[top]!=to) top--;for (int i=top; i<=s; i++) e[num].push_back((node){st[i],min(s-i+1,i-top)});tag[num]=s-top+1; top--;}}
}
void dp(int x, int fa){if (tag[x]==0){int mx1=0, mx2=0;for (int ed=1; ed<e[x].size(); ed++)if (e[x][ed].data!=fa){dp(e[x][ed].data,x);int now=f[e[x][ed].data]+e[x][ed].vote;if (now>mx1) mx2=mx1, mx1=now;else if (now>mx2) mx2=now;}ans=max(ans,mx1+mx2);f[x]=mx1;}else {for (int ed=1; ed<e[x].size(); ed++)if (e[x][ed].data!=fa){int t=e[x][ed].data;dp(e[x][ed].data,x);f[x]=max(f[e[x][ed].data]+e[x][ed].vote,f[x]); }for (int ed=1; ed<e[x].size(); ed++)if (e[x][ed].data!=fa) h[ed]=f[e[x][ed].data];else h[ed]=0;int pl=1, pr=0;for (int i=1; i<e[x].size(); i++){while (pl<=pr&&i-po[pl]>tag[x]/2) pl++;if (pl<=pr) ans=max(ans,h[i]+st[pl]+i-po[pl]);while (pl<=pr&&h[i]-i>=st[pr]-po[pr]) pr--;st[++pr]=h[i], po[pr]=i;}for (int i=1; i<e[x].size(); i++){while (pl<=pr&&i+tag[x]-po[pl]>tag[x]/2) pl++;if (pl<=pr) ans=max(ans,h[i]+st[pl]+i+tag[x]-po[pl]);while (pl<=pr&&h[i]-i-tag[x]>=st[pr]-po[pr]) pr--;st[++pr]=h[i], po[pr]=i+tag[x];}}
}
int main(){n=read(), m=read(); num=n; int sum=0;for (int i=1; i<=n; i++) e[i].push_back((node){0,0});for (int i=1; i<=m; i++){int l=read(),la=read();for (int j=2; j<=l; j++){int now=read();build(la,now,1);la=now;}}tarjan(1,0);for (int i=1; i<=n; i++) e[i].clear(), e[i].push_back((node){0,0});for (int i=n+1; i<=num; i++)for (int j=1; j<e[i].size(); j++) e[e[i][j].data].push_back((node){i,e[i][j].vote});for (int i=1; i<=place; i++)build(su[i],sv[i],1);dp(1,0);printf("%d\n",ans);return 0;
}

[bzoj1023][SHOI2008]cactus仙人掌图【仙人掌】相关推荐

  1. BZOJ1023[SHOI2008]cactus仙人掌图 【仙人掌DP】

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

  2. 2018.10.29 bzoj1023: [SHOI2008]cactus仙人掌图(仙人掌+单调队列优化dp)

    传送门 求仙人掌的直径. 感觉不是很难. 分点在环上面和不在环上分类讨论. 不在环上直接树形dpdpdp. 然后如果在环上讨论一波. 首先对环的祖先有贡献的只有环上dfsdfsdfs序最小的点. 对答 ...

  3. BZOJ1023 [SHOI2008]cactus仙人掌图

    滚回第一页去了... 好吧,看了题解蒟蒻也写不粗来,怎么办捏? 看这个吧:Orz YDC巨巨:但是巨巨写的程序又不优美,于是程序Orz hzwer 其实这题的重点在于tarjan和单调队列dp里&qu ...

  4. Acwing 360. Freda的传呼机(仙人掌图重构,lca)

    为了随时与rainbow快速交流,Freda制造了两部传呼机.Freda和rainbow所在的地方有N座房屋.M 条双向光缆. 每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传递,并且传呼机的信号 ...

  5. [BZOJ]1023: [SHOI2008]cactus仙人掌图

    Time Limit: 1 Sec  Memory Limit: 162 MB Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这 ...

  6. bzoj 1023: [SHOI2008]cactus仙人掌图(仙人掌求直径)

    1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 3668  Solved: 1535 [Submi ...

  7. BZOJ 1023: [SHOI2008]cactus仙人掌图

    1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2907  Solved: 1212 [Submi ...

  8. [SHOI2008]cactus仙人掌图

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

  9. 【刷题】BZOJ 1023 [SHOI2008]cactus仙人掌图

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

最新文章

  1. 用JAVA操作ClearCase
  2. 仓位 001 998 AUFNAHME不存在(L9009)
  3. df命令,du命令,磁盘分区
  4. android的logcat详细用法
  5. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)...
  6. php常见问题及其解决方案,PHP开源开发框架ZendFramework使用中常见问题说明及解决方案...
  7. 测试用例文档_如何设计测试用例
  8. php 生成xls解决乱码,怎么解决php导出excel文件乱码问题
  9. Maven引入数据库JDBC驱动
  10. 华为交换机查看当前配置
  11. 项目练习:在线抽奖系统
  12. chainlink2022年春季编程马拉松
  13. 2018年系统架构设计师案例分析真题及详细答案解析
  14. android P adb shell dumpsys battery 使用
  15. 房地产稳经济作用正在显现
  16. 网页设计:Meta标签详解
  17. 根据出生日期计算年龄(精确到天)
  18. Vue3通透教程【四】Vue3组合API初体验
  19. [转载]CodeGear RAD 2007 SP4 最新下载及破解
  20. Win11本地用户和组怎么管理?Win11创建用户管理员的方法

热门文章

  1. 【虹科云展厅专题】虹科赋能汽车智能化云展厅——汽车总线专题
  2. c语言程序设计中国传媒大学,中国传媒大学82《程序设计》考试大纲.doc
  3. 麒麟操作系统iso文件中的img文件的解压与压缩
  4. GET请求里的body问题
  5. ANO匿名飞控STM32代码解读(一)任务调度——Ano_Scheduler.c
  6. uni-app 保存图片到本地相册
  7. 视频火焰烟雾光线闪电科技粒子破碎特效PR标题模板
  8. ArkID 一账通:企业级开源IDaaS/IAM平台系统
  9. webapp期末作业-oneapp
  10. 设计模式 -- 单例模式(Singleton)