POJ2114 Boatherds 点分治
来源:互联网 发布:小甲鱼python解压密码 编辑:程序博客网 时间:2024/05/22 12:06
/* 题目描述:给定一棵有n(0 < n < 1e4)个节点的树,给出不超过100个询问,对于每次询问给出一个x,问树中是否存在点对之间的 距离恰好为x 方法:比较直接的点分治问题,与poj1741不同的地方是不能直接双指针来扫,而是用二分来查找统计和恰好为x的点对,复杂度 O(100 * n *logn * logn)*/#pragma warning(disable:4786)#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<map>#include<set>#include<vector>#include<cmath>#include<string>#include<sstream>#include<bitset>#define LL long long#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)#define mem(a,x) memset(a,x,sizeof(a))#define lson l,m,x<<1#define rson m+1,r,x<<1|1using namespace std;const int INF = 0x3f3f3f3f;const int mod = 1e9 + 7;const double PI = acos(-1.0);const double eps=1e-6;const int maxn = 1e4 + 5;int size[maxn] , maxv[maxn] , vis[maxn] , dis[maxn];int x[105] , cnt[105] , up[maxn] , low[maxn];int ans , root , Max , num ,n , m;int tot;int head[maxn] ;int lowbsearch(int left , int right , int val){ int mid , ret = -1; while(left <= right){ mid = left + (right - left) / 2; if(dis[mid] == val){ ret = mid; right = mid - 1; } else if(dis[mid] > val) right = mid - 1; else left = mid + 1; } return ret;}int upbsearch(int left , int right , int val){ int mid , ret = -1; while(left <= right){ mid = left + (right - left) / 2; if(dis[mid] == val){ ret = mid; left = mid + 1; } else if(dis[mid] > val) right = mid - 1; else left = mid + 1; } return ret;}struct node{ int v, w, nt;}edges[maxn * 2];void init(){ tot = 0; mem(vis , 0); mem(head , -1);}void add_edge(int u , int v , int w){ edges[tot].v = v; edges[tot].w = w; edges[tot].nt = head[u]; head[u] = tot++;}void dfssize(int u , int fa){ size[u] = 1; maxv[u] = 0; for(int i = head[u] ; i != -1 ; i = edges[i].nt){ int v = edges[i].v ; if(vis[v] || v == fa) continue; dfssize(v , u); size[u] += size[v]; maxv[u] = max(maxv[u] , size[v]); }}void dfsroot(int r , int u , int fa){ if(size[r] - size[u] > maxv[u]) maxv[u] = size[r] - size[u]; if(maxv[u] < Max) { Max = maxv[u]; root = u; } for(int i = head[u] ; i!= -1 ; i = edges[i].nt){ int v = edges[i].v; if(vis[v] || v == fa) continue; dfsroot(r , v , u); }}void dfsdis(int u , int d , int fa){ dis[num++] = d; for(int i = head[u] ; i != -1 ; i = edges[i].nt){ int v = edges[i].v; if(vis[v] || v == fa) continue; dfsdis(v , d + edges[i].w , u); }}void calc(int u , int d , int sgn){ num = 0; dfsdis(u , d , 0); sort(dis , dis + num); for(int k = 1 ; k<= m ; k++){ int i = 0 , j = num - 1; for(i = 0 ; i < num - 1; i++){ if(dis[i] > x[k]) break; int pos1 = lowbsearch(i + 1 , num - 1 , x[k] - dis[i]); if(pos1 == -1) continue; int pos2 = upbsearch(i + 1 , num - 1 , x[k] - dis[i]); cnt[k] += sgn * (pos2 - pos1 + 1); } }}void dfs(int u){ Max = n; dfssize(u , 0); dfsroot(u , u , 0); calc(root , 0 , 1); vis[root] = 1; for(int i = head[root]; i !=- 1 ; i = edges[i].nt){ int v= edges[i].v; if(!vis[v]){ calc(v , edges[i].w , -1); dfs(v); } }}int main(){ while(scanf("%d" , &n) != EOF){ if(!n) break; m = 0; mem(cnt , 0); init(); int c , d , query; for(int i = 1 ; i<= n ; i++){ while(scanf("%d" , &c) && c){ scanf("%d" , &d); add_edge(i , c , d); add_edge(c , i , d); } } while(scanf("%d" , &query) && query != 0){ x[++m] = query; } dfs(1); for(int i = 1 ; i<= m ; i++){ if(cnt[i]) puts("AYE"); else puts("NAY"); } puts("."); } return 0;}
0 0
- POJ2114 Boatherds 点分治
- [POJ2114]Boatherds(点分治+二分)
- [树的点分治] [POJ2114] Boatherds
- 【POJ2114】Boatherds 树分治
- poj2114 Boatherds
- poj2114 Boatherds
- POJ2114-Boatherds
- poj2114 Boatherds
- poj2114(树的点分治)
- poj 2114 Boatherds 点分治
- 【POJ】2114 Boatherds 点分治
- POJ 2114 Boatherds 点分治
- POJ 2114 Boatherds 点分治
- Poj 2114 Boatherds(点分治)
- 点分治练习poj1741;poj2114;bzoj2599
- POJ 2114 Boatherds【Tree,点分治】
- POJ 2114 Boatherds (树上点分治)
- poj 2114 Boatherds (点分治)
- 同步和异步
- 2016秋季找工作纪实
- 蓝桥杯 算法训练 出现次数最多的整数
- leetcode python 461
- 洛谷 1057——台阶问题(递推与递归二分)
- POJ2114 Boatherds 点分治
- SQLite笔记
- malloc实现原理&指针的步长与指针的字节长度的区别
- linux常用命令
- Spring定时任务的几种实现
- 点炸弹(bfs+剪枝,或链式向前星+剪枝+bfs)
- 深度感知简介
- Android -- Android设备的启动流程概述
- 洛谷 1057——传球游戏(递推与递归二分)