Description
The pricing policy of the Boatherds is very simple: each segment of each river between two villages is assigned a price (the price is same in both directions), so if a tourist requests a journey between any two villages, the ticket office clerks just add the prices of the segments along the only path between the villages.
One day, a very strange tourist appeared. She told the clerks that she returns to her country on the next day and she wants to spend all the remaining money on a boat trip, so they should find a route with exactly this cost. Being just poor (ahem) businessmen, they have asked the Abacus Calculator Makers for help.
You are given a description of the river network with costs of river segments and a sequence of integers x1,..., xk. For each xi, you should determine if there is a pair of cities (a, b) in the river network such that the cost of the trip between a and b is exactly xi.
Input
- A single line containing a single integer: the number of villages N (1 <= N <= 10 000).
- N lines describing the villages. The i-th of these lines (1 <= i <= N) describes the village with number i. It contains space separated integers d1, c1, d2, c2, , dki, cki, 0. The dj's are numbers of villages from which the rivers flow directly to the village i (with no other villages in between), each cj is the price of the journey between villages i and dj. Moreover, 2 <= dj <= N and 0 <= cj <= 1 000. Village 1 always corresponds to the mouth of the largest river, therefore no di can ever be equal to 1.
- M <= 100 lines describing the queries. The i-th of these lines corresponds to the i-th query and contains a single integer xi (1 <= xi <= 10 000 000).
- The instance is finished by a single line containing the number 0.
The whole input is ended by a single line containing the number 0.
Output
Output for each instance must be followed by a single line containing just the dot character.
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的路径……对于询问一个一个点分治……反正n才10000m才100
输入好蛋疼……第一行n,接下来n行,每两个数ci、di,表示i和ci有长度为di的边,以0结束。接下来输入询问,以0结束。又有多组数据,以0结束
#include<cstdio>
#include<iostream>
#include<cstring>
#define LL long long
#define N 40010
#define mod 10207
using namespace std;
inline LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct edge{int to,next,v;}e[2*N];
struct hashing{int v,next;}hash[2*N];
int he[N],head[N];
int f[N],son[N],s[N],d[N],query[N];
bool vis[N],ok[N];
int n,m,cnt,tot,root,sum,len,ans;
inline void ins(int u,int v,int w)
{
e[++cnt].to=v;
e[cnt].v=w;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void insert(int u,int v,int w)
{
ins(u,v,w);
ins(v,u,w);
}
inline void inh(int u)
{
int w=u%mod+132;
hash[++tot].v=u;
hash[tot].next=he[w];
he[w]=tot;
}
inline bool fnd(int u)
{
if (u<0)return 0;
int w=u%mod+132;
for (int i=he[w];i;i=hash[i].next)
if (u==hash[i].v)return 1;
return 0;
}
inline void getroot(int x,int fa)
{
son[x]=1;f[x]=0;
for (int i=head[x];i;i=e[i].next)
if (fa!=e[i].to&&!vis[e[i].to])
{
getroot(e[i].to,x);
son[x]+=son[e[i].to];
f[x]=max(f[x],son[e[i].to]);
}
f[x]=max(f[x],sum-son[x]);
if (f[x]<f[root])root=x;
}
inline void dfs(int x,int fa)
{
s[++len]=d[x];
for (int i=head[x];i;i=e[i].next)
if (!vis[e[i].to]&&fa!=e[i].to)
{
d[e[i].to]=d[x]+e[i].v;
dfs(e[i].to,x);
}
}
inline void solve(int x)
{
vis[x]=1;tot=0;
memset(he,0,sizeof(he));inh(0);
for (int i=head[x];i;i=e[i].next)
if (!vis[e[i].to])
{
len=0;
d[e[i].to]=e[i].v;
dfs(e[i].to,0);
for (int j=1;j<=m;j++)
{
if (ok[j])continue;
for (int k=1;k<=len;k++)
if (fnd(query[j]-s[k]))
{
ok[j]=1;
break;
}
}
for (int j=1;j<=len;j++)inh(s[j]);
}
for (int i=head[x];i;i=e[i].next)
if (!vis[e[i].to])
{
sum=son[e[i].to];
root=0;
getroot(e[i].to,0);
solve(root);
}
}
inline void work()
{
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(ok,0,sizeof(ok));
cnt=ans=0;
for(int i=1;i<=n;i++)
{
int x=read(),y;
while (x)
{
y=read();
insert(i,x,y);
x=read();
}
}
m=0;
int xx=read();
while (xx)
{
query[++m]=xx;
xx=read();
}
f[0]=n+1;sum=n;root=0;
getroot(1,0);
solve(root);
for (int i=1;i<=m;i++)
if (ok[i])printf("AYE\n");else printf("NAY\n");
printf(".\n");
}
int main()
{
while (~scanf("%d",&n)&&n)work();
}