POJ 2114 Boatherds
2017-09-22 23:45
225 查看
POJ 2114 Boatherds
点分治题意
给一棵带边权的树,给一系列询问,问是否存在一条路径,使得路上权值和恰好为K。思路
点分治。100个询问,每次做一遍点分治。点分治记录所有路径长度,在二分查找是否有满足条件的长度。
代码
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int MAXN=20005; struct Edge { int to, ne; int w; }e[MAXN*2+7]; int edgenum, head[MAXN]; void addedge(int from, int to, int w) { e[edgenum].to=to, e[edgenum].w=w, e[edgenum].ne=head[from], head[from]=edgenum++; e[edgenum].to=from, e[edgenum].w=w, e[edgenum].ne=head[to], head[to]=edgenum++; } int sz[MAXN], mx[MAXN], root, vis[MAXN]; void getrt(int x, int f, int n)//找x的子树内的重心root { sz[x]=1;mx[x]=0; for(int i=head[x];~i;i=e[i].ne) { int to=e[i].to; if(to==f||vis[to]) continue; getrt(to, x, n); sz[x]+=sz[to]; mx[x]=max(mx[x], sz[to]); } mx[x]=max(mx[x], n-sz[x]); if(mx[x]<mx[root]) root=x; } int dis[MAXN], discnt; int d[MAXN]; void getdis(int x, int f) { dis[discnt++]=d[x]; for(int i=head[x];~i;i=e[i].ne) { int to=e[i].to; if(to==f||vis[to]) continue; d[to]=(d[x]+e[i].w); getdis(to, x); } } int calc(int x, int nowd, int k) { discnt=0; d[x]=nowd; getdis(x, -1); int cnt=0; sort(dis, dis+discnt); for(int i=0;i<discnt;i++) { if(dis[i]+dis[i]>k) break; int yu=k-dis[i]; int l=i+1, r=discnt-1; int resl=0, resr=-1; while(l<=r) { int mid=(l+r)>>1; if(dis[mid]==yu) r=mid-1, resl=mid; else if(dis[mid]<yu) l=mid+1; else r=mid-1; } l=i+1, r=discnt-1; while(l<=r) { int mid=(l+r)>>1; if(dis[mid]==yu) l=mid+1, resr=mid; else if(dis[mid]<yu) l=mid+1; else r=mid-1; } cnt+=(resr-resl+1); } return cnt; } int ans; void work(int x, int k) { vis[x]=1; ans+=calc(x, 0, k); for(int i=head[x];~i;i=e[i].ne) { if(vis[e[i].to]) continue; ans-=calc(e[i].to, e[i].w, k); root=0; getrt(e[i].to, -1, sz[e[i].to]); work(root, k); } } int main() { int n=0; while(scanf("%d", &n)==1&&n) { memset(head, -1, sizeof(head)); edgenum=0; for(int i=1;i<=n;i++) { int a, b; while(scanf("%d", &a)==1&&a) { scanf("%d", &b); addedge(i, a, b); } } int q, qcnt=0; while(scanf("%d", &q)==1&&q) { memset(vis, 0, sizeof(vis)); discnt=0; mx[0]=0x3f3f3f3f;ans=0;root=0; getrt(1, -1, n); work(root, q); //printf("%d\n", ans); printf("%s\n", ans>0 ? "AYE" : "NAY"); } puts("."); } return 0; }
相关文章推荐
- POJ 2114 Boatherds 树分治
- 【POJ】2114 Boatherds 点分治
- poj 2114 Boatherds (点分治)
- POJ 2114 Boatherds
- 【poj2114】 Boatherds
- poj 2114 Boatherds 树的分治
- POJ 题目2114 Boatherds(树的点分治)
- POJ 2114 Boatherds【Tree,点分治】
- [树的点分治] [POJ2114] Boatherds
- POJ 2114 Boatherds (树上点分治)
- poj 2114 Boatherds 树的分治
- POJ2114 Boatherds 点分治
- POJ 2114 Boatherds 点分治
- 【POJ2114】Boatherds 树分而治之
- poj 2114 Boatherds
- POJ 2114 Boatherds
- POJ 2114 Boatherds 笔记
- [POJ2114]Boatherds(点分治+二分)
- POJ 2114 Boatherds 树的分治
- 【POJ2114】Boatherds 树分治