【JZOJ4715】树上路径
来源:互联网 发布:h5 全景相片源码 编辑:程序博客网 时间:2024/03/28 17:01
Description
给出一棵树,求出最小的k,使得,且在树中存在路径p,使得k>=S且k<=E。(k为路径p上的边的权值和)
题目描述使人神清气爽。——LYD729
Solution
树上多条路径问题显然用点分治解决。
于是像常规点分治那样,求出每个点到重心的距离,排序。然后枚举开头,二分出一个位置使得距离大于等于下界,然后如果这两个点在同一棵子树就把二分出的点跳到另一棵子树上。
Code
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 100001#define M 200001using namespace std;int p,q;int to[M],next[M],last[M],num=0;int val[M];int siz[N];int dis[N];int fa[N];int f[N];bool vis[N];struct node{ int x,f;}d[N];int tot;void link(int x,int y,int c){ num++; to[num]=y; next[num]=last[x]; last[x]=num; val[num]=c;}bool cmp(node x,node y){ return x.x<y.x;}int rt;int cnt=0;void get(int x,int t,int from){ for(int i=last[x];i;i=next[i]) { int v=to[i]; if(v!=t && !vis[v]) { dis[v]=dis[x]+val[i]; get(v,x,from); } } if(dis[x]) { tot++; d[tot].x=dis[x]; d[tot].f=from; }}void find(int x,int p,int t){ siz[x]=1; f[x]=0; for(int i=last[x];i;i=next[i]) { int v=to[i]; if(v!=t && !vis[v]) { find(v,p,x); siz[x]+=siz[v]; f[x]=max(f[x],siz[v]); } } f[x]=max(f[x],p-siz[x]); if(f[x]<f[rt]) rt=x;}int ans=2147483647;int nx[N];void calc(){ sort(d+1,d+tot+1,cmp); nx[tot]=tot+1; fd(i,tot-1,1) if(d[i].f==d[i+1].f) nx[i]=nx[i+1]; else nx[i]=i+1; if(tot==1 && d[1].x>=p && d[1].x<=q && d[1].x<ans) ans=d[1].x; fo(i,1,tot-1) { if(d[i].x>=p && d[i].x<ans) ans=d[i].x; int l=i+1,r=tot; while(l+1<r) { int mid=(l+r)/2; if(d[i].x+d[mid].x>=p) r=mid; else l=mid; } int t=l; if(d[i].x+d[t].x<p) t++; while(d[i].f==d[t].f) t=nx[t]; if(t>tot) continue; if(d[i].x+d[t].x>=p && d[i].x+d[t].x<=q) { if(ans>d[i].x+d[t].x) ans=d[i].x+d[t].x; } }}void dfs(int x,int t){ vis[x]=true; tot=0; dis[x]=0; for(int i=last[x];i;i=next[i]) { int v=to[i]; if(v!=t && !vis[v]) { dis[v]=val[i]; get(v,x,v); } } calc(); for(int i=last[x];i;i=next[i]) { int v=to[i]; if(!vis[v] && v!=t) { rt=0; find(v,siz[v],x); dfs(rt,x); } }}int main(){ int n; cin>>n>>p>>q; fo(i,1,n-1) { int x,y,c; scanf("%d %d %d",&x,&y,&c); link(x,y,c); link(y,x,c); } rt=0; f[0]=2147483647; find(1,n,0); dfs(rt,0); if(ans>q) cout<<-1; else cout<<ans;}
2 0
- 【JZOJ4715】树上路径
- Jzoj4715 树上路径
- JZOJ4715树上路径 点分治
- 【jzoj4715】【树上路径】【树】【分治】【点分治】
- 【JZOJ4715】【NOIP2016提高A组模拟8.19】树上路径
- 树上路径
- 树上路径
- 树上路径
- noip2013truck树上路径倍增
- 树上的路径
- [bzoj3784]树上的路径
- 树上最长单色路径
- 树上最长单色路径
- 树上最长单色路径
- 3784: 树上的路径
- 【JZOJ 4715】 树上路径
- 【JZOJ 4715】树上路径
- 【NOIP提高】树上路径
- JZOJ4714公约数 找规律
- Qt中int转换成QString
- 木雨音乐 项目开发(六)音乐播放界面PlayActivity实现
- 使用Android Studio导入源码
- 第二十一条:函数对象表示策略
- 【JZOJ4715】树上路径
- Mac上搭建php环境
- 关于socket的整理
- 利用分拣存储实现1:N
- Qt的QString类补0占位输出sprintf
- dyld: Symbol not found: ___NSArray0__
- 修改档案/目录权限问题
- Web Service学习小结——JAX-WS CXF AXIS2关系
- QT int long 转换char string