[BZOJ2599][IOI2011]Race(点分治)
2016-09-20 14:34
369 查看
题目描述
传送门题解
同样是树上的路径,点分的思路是很显然的。不过需要同时满足两个条件。观察可以发现路径长度=k可以作为点分判断的条件,那么我们需要把最小的边数转化成判断存在性问题。
每一次遍历等于是给出了一些点,每个点有权,问权值和=k的点对数量。那么显然排序后又可以用两个指针lr扫出来。时间复杂度O(nlogn)。
最后从小向大扫就可以了。总体时间复杂度O(nlog2n)。
代码
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 200005 #define INF 2000000000 int n,k,x,y,z,sum,root,cnt; int tot,point ,nxt[N*2],v[N*2],c[N*2]; int size ,big ,dis ,deep ,ans ; struct hp{int dis,deep;}pt ; bool vis ; 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"); }
总结
①求最小/最大值问题可以转化为判断存在性问题。并且在点分中的加加减减比较好用。相关文章推荐
- BZOJ 2599: [IOI2011]Race [点分治]
- BZOJ 2599 IOI 2011 Race 树的分治
- BZOJ2599: [IOI2011]Race 点分治
- 【点分治】BZOJ 2599:[IOI2011]Race
- BZOJ_2599_[IOI2011]Race_点分治
- 【BZOJ】2599: [IOI2011]Race 点分治
- 【BZOJ】2599 [IOI2011]Race 点分治
- [bzoj2599][IOI2011]Race——点分治
- Bzoj 2599: [IOI2011]Race(点分治)
- bzoj2599: [IOI2011]Race 点分治
- 【BZOJ2599】[IOI2011]Race【点分治】
- bzoj 2599: [IOI2011]Race(树的点分治)
- BZOJ2599 [IOI2011] [Race] 点分治
- bzoj 2599: [IOI2011]Race (点分治)
- [BZOJ2599][IOI2011]Race 点分治
- BZOJ.2599.[IOI2011]Race(点分治)
- [bzoj2599][IOI2011]Race_树上点分治
- [BZOJ2599][IOI2011]Race(点分治)
- BZOJ 2599: [IOI2011]Race (点分治)
- 【BZOJ 2599】 [IOI2011]Race 树的点分治