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 "); else printf("NAY "); } printf(". "); } return 0; }