[IOI2008]Island
题目大意:
找基环树直径
(这个题输入给出的是内向基环树(虽然是无向边))
存在两种情况:
1.直径在树上。
2.直径从树里走到环上,再走进另外一个树里。
首先dfs找到环。
第一种直接树形dp。dp[i]i往下最长路径。还能用来求第二种情况。
第二种,找到环之后,断环成链,复制一倍。求的是,选择距离小于环长的两个点,贡献是两个点的dp[i],和两个点之间的距离。这个用单调队列优化dp即可。
bzoj会爆栈mmp
如果你是ywy可以bfs求树形dp
其实,这是一个内向基环树,所以,直接topo排序,从叶子往上面topo
即可求得dp,还能求得环。
代码:(dfs爆栈版)
#pragma comment(linker, "/STACK:102400000,102400000") #include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using namespace std; typedef long long ll; void rd(int &x){char ch;x=0;while(!isdigit(ch=getchar()));for(x=numb;isdigit(ch=getchar());x=x*10+numb); } namespace Miracle{ const int N=1e6+5; int n; struct node{int nxt,to;ll val; }e[2*N]; int hd[N],cnt=1; void add(int x,int y,int z){e[++cnt].nxt=hd[x];e[cnt].to=y;e[cnt].val=z;hd[x]=cnt; } bool vis[N]; bool on[N];//on the huan bool in[N]; int to[N],v[N]; int sta[N],top; int len;//huan chang int mem[2*N],tot; ll cos[2*N]; int q[2*N],l,r; ll f[N]; ll ans; ll sum; ll zhi; bool fl; void dfs(int x,int in_edge){ // cout<<" dfs "<<x<<" "<<fl<<" "<<top<<endl;vis[x]=1;sta[++top]=x;for(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;if(i==(in_edge^1)) continue;if(!vis[y]){dfs(y,i);}else if(!fl){fl=true;// cout<<" find "<<top<<" : "<<sta[top]<<endl;int z;do{z=sta[top];on[z]=1;mem[++len]=z;top--;}while(z!=y);}}if(sta[top]==x) --top;//warning!!! } void dp(int x,int fa){//find farthestfor(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;if(y==fa) continue;if(on[y]) continue;dp(y,x);zhi=max(zhi,f[x]+e[i].val+f[y]);f[x]=max(f[x],e[i].val+f[y]);} } ll wrk(int st){sum=0;len=0;fl=false;top=0;dfs(st,0);for(reg i=1;i<=len;++i){zhi=0;dp(mem[i],0);sum=max(sum,zhi);mem[i+len]=mem[i];}l=1,r=0;cos[1]=0;for(reg i=2;i<=2*len;++i){cos[i]=(to[mem[i]]==mem[i-1])?v[mem[i]]:v[mem[i-1]];cos[i]+=cos[i-1];}for(reg i=1;i<=2*len;++i){while(l<=r&&i-q[l]>=len) ++l;if(i!=1) sum=max(sum,f[mem[q[l]]]-cos[q[l]]+cos[i]+f[mem[i]]);while(l<=r&&f[mem[q[r]]]-cos[q[r]]<=f[mem[i]]-cos[i]) --r;q[++r]=i;}return sum; } int main(){rd(n);int x;int z;for(reg i=1;i<=n;++i){rd(x);rd(z);to[i]=x;v[i]=z;add(i,x,z);add(x,i,z);}for(reg i=1;i<=n;++i){if(!vis[i]){ans+=wrk(i);}}printf("%lld",ans);return 0; }} int main(){Miracle::main();return 0; }/*Author: *Miracle*Date: 2018/11/4 9:27:26 */
转载于:https://www.cnblogs.com/Miracevin/p/9903327.html
[IOI2008]Island相关推荐
- bzoj1791: [Ioi2008]Island 岛屿 单调队列优化dp
1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 1826 Solved: 405 [Submit] ...
- P4381 [IOI2008]Island
P4381 [IOI2008]Island 题意: 给你一棵基环树森林,求出基环树的直径之和. 题解: 对于基环树,我们将环看作根,那么直径有两种情况:: 1.不经过环,也就是环上某个点的子树内部,对 ...
- [ioi2008]Island 岛屿
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
- 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)
1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 908 Solved: 159 [Su ...
- 【BZOJ1791】【IOI2008】【基环树】island(status速度第一)
1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 908 Solved: 159 [Su ...
- 数据结构之基环树——骑士,Island,旅行加强版,Number of Simple Paths,Traffic Network in Numazu,Card Game
文章目录 [ZJOI2008]骑士 [IOI2008] Island [NOIP2018 提高组] 旅行 加强版 CF1454E Number of Simple Paths Traffic Netw ...
- java异步处理同步化_java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring EventListener,超时处理和空循环性能优化...
异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 正常处理逻辑 触发异步操作,然后传递一个唯一标识. 等到异步结果返回,根据传入的唯一标识,匹配此次结果. 如何转换为同步 ...
- 基础省选+NOI-第4部分 动态规划
1.期望概率DP [整理]简单的数学期望和概率DP [整理]简单的数学期望和概率DP - nimphy - 博客园 期望&概率dp总结 期望&概率dp总结_十分残念的博客-CSDN博客 ...
- android studio 混淆包,gogoapp体育-官网首页
一.密码 1.在阅读项目代码时,对于 #pragma warning(disable : 4251) 这个语句不是很理解,现在有时间查阅了一些资料整理如下,以备以后查找使用,也给对此有疑问提的朋友一个 ...
最新文章
- 谷歌发布最新看图说话模型,可实现零样本学习,多类型任务也能直接上手
- Oracle Sql Developer
- 深夜,你的手机为谁开?
- SAP 业务常用表的收集
- linux下软件实施,linux系统未来或应用广泛
- 牛客 contest893 G-Truthman or Fakeman
- 交换ctrl和左caps_如何在Linux中交换Ctrl和Caps Lock键
- 黑客勒索遭遇霸气回应:不怕,我们有备份
- 50多条mysql数据库优化建议
- 鼠标追踪技术:研究内部信息加工过程
- 系统封装到底有个什么用
- 常见文章、图文素材采集软件优缺点比较分析
- Java如何将文件打包成Zip、Rar压缩包
- 程序员去外包的后遗症是什么
- 本地HTML文件 带参数方案
- 洛谷P1796 汤姆斯的天堂梦
- 2016即将结束,你的目标实现了吗?
- 关于CSDN博客待审核的问题
- 【JiyaChieng】(零)Jiya和Chieng的故事
- RFID电子标签的分类