[BZOJ2599][IOI2011]Race(点分治)
来源:互联网 发布:志鸿优化系列丛书 编辑:程序博客网 时间:2024/06/05 18:55
题目描述
传送门
题解
同样是树上的路径,点分的思路是很显然的。不过需要同时满足两个条件。
观察可以发现路径长度=k可以作为点分判断的条件,那么我们需要把最小的边数转化成判断存在性问题。
每一次遍历等于是给出了一些点,每个点有权,问权值和=k的点对数量。那么显然排序后又可以用两个指针lr扫出来。时间复杂度
最后从小向大扫就可以了。总体时间复杂度
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 200005#define INF 2000000000int n,k,x,y,z,sum,root,cnt;int tot,point[N],nxt[N*2],v[N*2],c[N*2];int size[N],big[N],dis[N],deep[N],ans[N];struct hp{int dis,deep;}pt[N];bool vis[N];void addedge(int x,int y,int z){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z; ++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; c[tot]=z;}void getroot(int x,int fa){ size[x]=1; big[x]=0; for (int i=point[x];i;i=nxt[i]) if (v[i]!=fa&&!vis[v[i]]) { getroot(v[i],x); size[x]+=size[v[i]]; big[x]=max(big[x],size[v[i]]); } big[x]=max(big[x],sum-size[x]); if (big[x]<big[root]) root=x;}void getdeep(int x,int fa){ pt[++cnt].dis=dis[x],pt[cnt].deep=deep[x]; for (int i=point[x];i;i=nxt[i]) if (v[i]!=fa&&!vis[v[i]]) { dis[v[i]]=dis[x]+c[i]; deep[v[i]]=deep[x]+1; getdeep(v[i],x); }}int cmp(hp a,hp b){ return a.dis<b.dis;}void calc(int x,int nowdis,int nowdeep,int add){ dis[x]=nowdis; deep[x]=nowdeep; cnt=0; getdeep(x,0); sort(pt+1,pt+cnt+1,cmp); for (int l=1,r=cnt;l<=r;l++) { while (l<r&&pt[l].dis+pt[r].dis>k) r--; for (int i=r;pt[l].dis+pt[i].dis==k;i--) ans[pt[l].deep+pt[i].deep]+=add; }}void dfs(int x){ calc(x,0,0,1); vis[x]=true; for (int i=point[x];i;i=nxt[i]) if (!vis[v[i]]) { calc(v[i],c[i],1,-1); sum=size[v[i]]; root=0; getroot(v[i],0); dfs(root); }}int main(){ scanf("%d%d",&n,&k); for (int i=1;i<n;++i) { scanf("%d%d%d",&x,&y,&z); x++; y++; addedge(x,y,z); } sum=n; root=0; big[0]=INF; getroot(1,0); dfs(root); for (int i=1;i<=n;++i) if (ans[i]) { printf("%d\n",i); return 0; } puts("-1");}
总结
①求最小/最大值问题可以转化为判断存在性问题。并且在点分中的加加减减比较好用。
0 0
- [BZOJ2599][IOI2011]Race(点分治)
- [BZOJ2599][IOI2011]Race(点分治)
- 【bzoj2599】[IOI2011]Race 点分治
- 【BZOJ2599】[IOI2011]Race【点分治】
- BZOJ2599: [IOI2011]Race 点分治
- bzoj2599: [IOI2011]Race 点分治
- BZOJ2599 [IOI2011] [Race] 点分治
- Bzoj2599:[IOI2011]Race:树的点分治
- [BZOJ2599][IOI2011]Race 树分治
- bzoj2599 [ IOI2011 ] -- 点分治
- [树的点分治] [树形DP] [BZOJ2599] [IOI2011] Race
- bzoj2599 Race 点分治
- 【bzoj2599】Race 点分治
- bzoj 2599: [IOI2011]Race (点分治)
- 【bzoj2559】【IOI2011】【Race】【点分治】
- 2599: [IOI2011]Race 点分治
- BZOJ_P2599 [IOI2011]Race(点分治)
- bzoj2599 [IOI2011]Race(定权值最短树上路径)
- python获取数组元素个数的方法
- 移动前端知识总结
- android之merge布局
- java中的匿名内部类总结
- 数据结构 学习笔记(三):线性结构:堆栈,队列,表达式求值,多项式加法运算
- [BZOJ2599][IOI2011]Race(点分治)
- 如何分析解决Android ANR
- Android滑动ScrollView时使导航栏停留的效果(仿ios的tableview分区)
- c++ 模板(Templates)
- 博客地址更新www.zt-zhaoteng.cn
- Proteus网络标号批量编号
- 关于责任心
- 热血群英传隐私政策
- Jmeter 脚本录制