NOIP提高组【JZOJ4805.】跟踪
来源:互联网 发布:大华行知实验幼儿园 编辑:程序博客网 时间:2024/06/06 19:11
Description
Data Constraint
Solution
这道题其实很简单。我们先将s视为树根,遍历一下,求出每个点作以他为根的子树的最大深度。然后我们将s到p和s到q的路径上的点都走一遍,求出不包括当前点x不包括s到p和s到q的路径上的点时以他为根的子树的最大深度,求一遍答案即可。
代码
#include<iostream>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=400005;int first[maxn],last[maxn],next[maxn],v[maxn],deep[maxn],mx[maxn],fa[maxn];int n,m,i,t,j,k,l,x,y,s,z,p,q,num,ln,fa2,fa1,ans,road[maxn],road1[maxn],num1;bool bz[maxn];void lian(int x,int y){ last[++num]=y;next[num]=first[x];first[x]=num;}void bfs(){ int i=0,j=1,t,k,l,x; v[1]=s;bz[s]=true;deep[s]=0; while (i<j){ x=v[++i]; for (t=first[x];t;t=next[t]){ if (bz[last[t]]) continue; v[++j]=last[t],fa[v[j]]=x;deep[v[j]]=deep[x]+1;bz[last[t]]=true; } } for (i=n;i>=1;i--) mx[fa[v[i]]]=max(mx[fa[v[i]]]+1,mx[v[i]]);}int main(){// freopen("track.in","r",stdin);freopen("track.out","w",stdout); scanf("%d%d%d%d",&n,&s,&p,&q); for (i=1;i<n;i++) scanf("%d%d",&x,&y),lian(x,y),lian(y,x); bfs();fa2=p;fa1=q;num=0;memset(bz,0,sizeof(bz)); while (fa2!=s) bz[fa2]=true,road[++num]=fa2,fa2=fa[fa2]; while (fa1!=s) bz[fa1]=true,road1[++num1]=fa1,fa1=fa[fa1]; mx[s]=1; bz[s]=true;mx[s]=0; for (t=first[s];t;t=next[t]) if (!bz[last[t]]) mx[s]=max(mx[last[t]]+1,mx[s]); if (mx[s]>=min(deep[p],deep[q])) ans=3*min(deep[p],deep[q]); else{ t=mx[s]+min(deep[p],deep[q]); k=t/2; ans=k*3; if (t%2) ans+=2; } l=0;x=deep[p],y=deep[q]; for (i=num;i>=1;i--){ x-=3; y--;z=road[i];mx[z]=0; if (x<=0 || y<=0){ if (x!=-2)ans=max(ans,l+2); else ans=max(ans,l+1);break; }l+=3; for (t=first[z];t;t=next[t]) if (!bz[last[t]])mx[z]=max(mx[last[t]]+1,mx[s]); if (mx[z]>=min(x,y)) ans=max(ans,l+3*min(x,y)); else{ t=mx[z]+min(x,y); k=t/2;k*=3; if (t%2) k+=2; ans=max(ans,l+k); } } l=0;x=deep[p],y=deep[q]; for (i=num1;i>=1;i--){ x--; y-=3;z=road1[i];mx[z]=0; if (x<=0 || y<=0){ if (y!=-2)ans=max(ans,l+2); else ans=max(ans,l+1);break; }l+=3; for (t=first[z];t;t=next[t]) if (!bz[last[t]])mx[z]=max(mx[last[t]]+1,mx[s]); if (mx[z]>=min(x,y)) ans=max(ans,l+3*min(x,y)); else{ t=mx[z]+min(x,y); k=t/2;k*=3; if (t%2) k+=2; ans=max(ans,l+k); } } printf("%d\n",ans);}
3 0
- NOIP提高组【JZOJ4805.】跟踪
- 【JZOJ4805】【NOIP2016提高A组模拟9.28】跟踪
- NOIP提高组 单峰
- NOIP提高组 积木
- NOIP提高组 看电影
- NOIP提高组 鼎纹
- NOIP提高组 千帆渡
- NOIP提高组 Brothers
- NOIP提高组 Crisis
- NOIP提高组 Word
- NOIP提高组 闭门造车
- NOIP提高组 爬山
- 【NOIP提高组】爬山
- 【NOIP提高组】Map
- 【NOIP提高组】矩阵
- 【NOIP提高组】整除
- 【NOIP提高组】神炎皇
- 【NOIP提高组】降雷皇
- GreenDao-多表关联
- file_put_contents在thinkphp中怎么使用,不生成文件的原因
- 《从零开始学Swift》学习笔记(Day 26)——可选链
- 归并排序
- Windows 通过 putty 连接 虚拟机下linux 问题
- NOIP提高组【JZOJ4805.】跟踪
- ExecutorService的十个使用技巧
- 读取txt列,python一行流
- Android 线程和线程池
- Struts2下传和上载CSV与Excel文件
- Java集合容器
- C++实现简单线程池
- 新建安卓项目注意事项
- Linux 之用户及文件权限管理