首页 > 代码库 > 【poj2114】 Boatherds
【poj2114】 Boatherds
http://poj.org/problem?id=2114 (题目链接)
题意
给出一棵树,问是否存在两点间的距离为K。
Solution
点分治嘛,跟poj1741差不多。。
然而为什么我调了一个下午。。map真是坑死了,各种TLE,以后再也不写了。
代码
// poj2114#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<set>#define LL long long#define MOD 100000000#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;set<int> s;const int maxn=10010;struct edge {int to,next,w;}e[maxn<<1];int head[maxn],size[maxn],deep[maxn],d[maxn],f[maxn],vis[maxn],ans[maxn],q[maxn];int m,sum,rt,n,cnt;void link(int u,int v,int w) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w; e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;}void Init() { cnt=0;f[0]=inf; for (int i=1;i<=n;i++) head[i]=f[i]=vis[i]=0;}void calroot(int x,int fa) { size[x]=1;f[x]=0; for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to] && e[i].to!=fa) { calroot(e[i].to,x); size[x]+=size[e[i].to]; f[x]=max(f[x],size[e[i].to]); } f[x]=max(f[x],sum-size[x]); if (f[x]<f[rt]) rt=x;}void caldeep(int x,int fa) { deep[++deep[0]]=d[x]; for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to] && e[i].to!=fa) { d[e[i].to]=d[x]+e[i].w; caldeep(e[i].to,x); }}void cal(int x,int now) { d[x]=now;deep[0]=0; caldeep(x,0); for (int i=1;i<=m;i++) if (!ans[i]) { for (int j=1;j<=deep[0];j++) if (q[i]>=deep[j]) { if (q[i]-deep[j]==0) ans[i]=1; else if (s.count(q[i]-deep[j])) ans[i]=1; } } for (int i=1;i<=deep[0];i++) s.insert(deep[i]);}void solve(int x) { vis[x]=1;s.clear(); for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) cal(e[i].to,e[i].w); for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) { sum=size[e[i].to]; rt=0;calroot(e[i].to,x); solve(rt); }}int main() { while (scanf("%d",&n)!=EOF && n) { Init(); for (int d,c,i=1;i<=n;i++) while (scanf("%d",&d)!=EOF && d) { scanf("%d",&c); link(i,d,c); } m=0;int x; while (scanf("%d",&x)!=EOF && x) q[++m]=x; for (int i=1;i<=m;i++) ans[i]=0; rt=0;sum=n; calroot(1,0); solve(rt); for (int i=1;i<=m;i++) { if (ans[i]) printf("AYE\n"); else printf("NAY\n"); } printf(".\n"); } return 0;}
【poj2114】 Boatherds
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。