标签:
Description
Input
Output
Sample Input
6 2 5 3 7 4 1 0 0 5 2 6 3 0 0 0 0 1 8 13 14 0 0
Sample Output
AYE AYE NAY AYE.
简单的树分治,统计长度为k的路径是否存在。
#include<map> #include<cstdio> #include<algorithm> using namespace std; const int maxn=1e5+10; const int INF=0x7FFFFFFF; int n,m,x,y; int p[maxn],t; bool flag[100]; struct Tree { int ft[maxn],nt[maxn],u[maxn],v[maxn],sz; int vis[maxn],mx[maxn],ct[maxn]; int d[maxn],tot; map<int,int> M; void clear(int n) { mx[sz=0]=INF; for (int i=1;i<=n;i++) ft[i]=-1,vis[i]=0; } void AddEdge(int x,int y,int z) { u[sz]=y; v[sz]=z; nt[sz]=ft[x]; ft[x]=sz++; u[sz]=x; v[sz]=z; nt[sz]=ft[y]; ft[y]=sz++; } int dfs(int x,int fa,int sum) { int y=mx[x]=(ct[x]=1)-1; for (int i=ft[x];i!=-1;i=nt[i]) { if (vis[u[i]]||u[i]==fa) continue; int z=dfs(u[i],x,sum); ct[x]+=ct[u[i]]; mx[x]=max(mx[x],ct[u[i]]); y=mx[y]<mx[z]?y:z; } mx[x]=max(mx[x],sum-ct[x]); return mx[x]<mx[y]?x:y; } void get(int x,int fa,int len) { d[tot++]=len; for (int i=ft[x];i!=-1;i=nt[i]) { if (vis[u[i]]||u[i]==fa) continue; get(u[i],x,len+v[i]); } } void find(int x) { M.clear(); M[0]=1; for (int i=ft[x];i!=-1;i=nt[i]) { if (vis[u[i]]) continue; tot=0; get(u[i],x,v[i]); for (int j=0;j<tot;j++) { for (int k=0;k<t;k++) { if (flag[k]) continue; if (M.count(p[k]-d[j])) flag[k]=true; } } for (int j=0;j<tot;j++) M[d[j]]=1; } } void work(int x,int sum) { int y=dfs(x,-1,sum); find(y); vis[y]=1; for (int i=ft[y];i!=-1;i=nt[i]) { if (vis[u[i]]) continue; work(u[i],ct[u[i]]>ct[y]?sum-ct[y]:ct[u[i]]); } vis[y]=0; } }solve; int main() { while (~scanf("%d",&n),n) { solve.clear(n); for (int i=1;i<=n;i++) { while (scanf("%d",&x),x) { scanf("%d",&y); solve.AddEdge(i,x,y); } } t=0; while (~scanf("%d",&p[t]),p[t]) flag[t++]=false; solve.work(1,n); for (int i=0;i<t;i++) printf("%s\n",flag[i]?"AYE":"NAY"); printf(".\n"); } return 0; }
标签:
原文地址:http://blog.csdn.net/jtjy568805874/article/details/51367441