题意
给一棵最多1W个节点的树,求是否存在点对使得他们的路径是k
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 10010;
const int INF = 0x3f3f3f3f;
int head[MAX], to[MAX << 1],len[MAX << 1], next[MAX << 1];
int sizee[MAX], deep[MAX], vis[MAX], son[MAX], dis[MAX];
int root, cnt, tot, ans, all;
void add(int x, int y, int z){
to[++cnt] = y, len[cnt] = z, next[cnt] = head[x], head[x] = cnt;
}
void getroot(int x, int fson) {
son[x] = 0;
sizee[x] = 1;
for(int i = head[x]; i; i = next[i]) {
if(to[i] != fson && !vis[to[i]]) {
getroot(to[i], x);
sizee[x] += sizee[to[i]];
son[x] = max(son[x], sizee[to[i]]);
}
}
son[x] = max(son[x], all - sizee[x]);
if(son[root] > son[x])
root = x;
}
void getdeep(int x, int fson) {
dis[++tot] = deep[x];
for(int i = head[x]; i; i = next[i]) {
if(to[i] != fson && !vis[to[i]]) {
deep[to[i]] = deep[x] + len[i];
getdeep(to[i], x);
}
}
}
int N, X;
int calc(int x) {
tot = 0;
getdeep(x, 0);
sort(dis, dis + tot + 1);;
int i = 1, j = tot, sum = 0;
while(i < j) {
if(dis[i] + dis[j] == X) {
sum += (j - i);
i++;
}
else if(dis[i] + dis[j] < X) i++;
else j--;
}
return sum;
}
void dfs(int x) {
deep[x] = 0;
vis[x] = 1;
ans += calc(x);
for(int i = head[x]; i; i = next[i]) {
if(!vis[to[i]]) {
deep[to[i]] = len[i];
ans -= calc(to[i]);
all = sizee[to[i]];
root = 0;
getroot(to[i], 0);
dfs(root);
}
}
}
int main() {
while(scanf("%d", &N) != EOF && N) {
memset(head, 0, sizeof(head));
for(int i = 1; i <= N; i++) {
int d, c;
while(scanf("%d", &d) != EOF && d) {
scanf("%d", &c);
add(i, d, c);
add(d, i, c);
}
}
while(scanf("%d", &X) != EOF && X) {
memset(vis, 0, sizeof(vis));
cnt = 0; ans = 0;
son[0] = INF;
all = N;
root = 0;
getroot(1, 0);
dfs(root);
//cout <<" " << ans << endl;
if(ans >= 1) printf("AYE\n");
else printf("NAY\n");
}
printf(".\n");
}
return 0;
}