POJ 2114 Boatherds (树上点分治)
来源:互联网 发布:js div height 编辑:程序博客网 时间:2024/05/16 06:55
题目地址:POJ 2114
点分治水题。只是把距离小于等于k改成了等于k。稍微加一点处理就可以了。
代码如下:
#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>#include <time.h>using namespace std;#define LL __int64#define pi acos(-1.0)//#pragma comment(linker, "/STACK:1024000000")const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-9;const int MAXN=20000+10;int head[MAXN], cnt, tot, tt, min1, n, root;int siz[MAXN], d[MAXN], dep[MAXN], ans[MAXN], q[MAXN], vis[MAXN];int c[MAXN], dp[MAXN];struct node{ int v, w, next;} edge[MAXN<<1];void add(int u, int v, int w){ edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++;}void init(){ memset(head,-1,sizeof(head)); cnt=tot=tt=0; memset(vis,0,sizeof(vis)); memset(ans,0,sizeof(ans));}void getroot(int u, int fa, int s){ siz[u]=1; int max1=0; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa||vis[v]) continue ; getroot(v,u,s); siz[u]+=siz[v]; max1=max(max1,siz[v]); } max1=max(max1,s-siz[u]); if(min1>max1){ root=u; min1=max1; }}void getdep(int u, int fa){ d[tot++]=dep[u]; siz[u]=1; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa||vis[v]) continue ; dep[v]=dep[u]+edge[i].w; getdep(v,u); siz[u]+=siz[v]; }}void Cal(int u, int len, int f){ tot=0; dep[u]=len; getdep(u,-1); sort(d,d+tot); int i, j, k, y=0; c[0]=d[0]; dp[0]=1; for(i=1;i<tot;i++){ if(d[i]!=d[i-1]){ dp[++y]=1; c[y]=d[i]; } else{ dp[y]++; } } for(i=0;i<tt;i++){ k=y; for(j=0;j<=y;j++){ while(c[j]+c[k]>q[i]&&k>j) k--; if(k==j&&c[j]+c[k]==q[i]) ans[i]+=f*(dp[j]*(dp[j]-1)/2); if(k<=j) break; if(c[j]+c[k]==q[i]) ans[i]+=f*dp[j]*dp[k]; } }}void work(int u){ Cal(u,0,1); vis[u]=1; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(vis[v]) continue ; Cal(v,edge[i].w,-1); min1=INF; getroot(v,-1,siz[v]); work(root); }}int main(){ int i, v, w, j, x; while(scanf("%d",&n)!=EOF&&n){ init(); for(i=1;i<=n;i++){ while(scanf("%d",&v)!=EOF&&v){ scanf("%d",&w); add(i,v,w); add(v,i,w); } } while(scanf("%d",&x)!=EOF&&x) q[tt++]=x; min1=INF; getroot(1,-1,n); work(root); for(i=0;i<tt;i++){ if(ans[i]) puts("AYE"); else puts("NAY"); } puts("."); } return 0;}
1 0
- POJ 2114 Boatherds (树上点分治)
- poj 2114 Boatherds 点分治
- 【POJ】2114 Boatherds 点分治
- POJ 2114 Boatherds 点分治
- POJ 2114 Boatherds 点分治
- Poj 2114 Boatherds(点分治)
- POJ 2114 Boatherds【Tree,点分治】
- poj 2114 Boatherds (点分治)
- POJ 题目2114 Boatherds(树的点分治)
- 【树分治】 POJ 2114 Boatherds
- POJ2114 Boatherds 点分治
- poj 2114 Boatherds 树的分治
- POJ 2114 Boatherds 树的分治
- POJ 2114Boatherds 树的分治
- poj 2114 Boatherds(树分治)
- POJ 1741 Tree(树上的点分治)
- POJ 1987 Distance Statistics 树上点分治
- POJ 1987 Distance Statistics (树上点分治)
- [leetcode] 101.Symmetric Tree
- 一致性hash
- Python:面向对象的“开闭原则”和“鸭子类型”
- Codeforces #309 Div 1 简要题解
- unity 加载c++ dll文件提示DllNotFoundException的解决办法
- POJ 2114 Boatherds (树上点分治)
- 抓包工具———wireshark学习篇:1
- ARM 浮点运算
- 十进制和其他进制的相互转化(自己写的)
- sh_Spring整合Hibernate
- properties属性文件
- 23.Merge K Sorted Lists
- 抓包工具---wireshark 学习篇:0
- 第一天的日记