跟poj 1114差不多的题。。。求是否存在长为X的路径
开始的时候是vector建边,但是超时了,最后找来找去发现是clear的次数太多了,无奈之下,还是换回朴素建边了,哎,以后数据量大的题还是避免STL吧
自己写的calc函数挫的要死,于是从网上淘了一个清晰的。。。
http://blog.csdn.net/sdj222555/article/details/7908842
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 22222;
struct Divided_Conquer {
struct Edge{
int v , w , next;
Edge(){}
Edge(int v,int w): v(v),w(w) {
}
}edge[maxn];
int E ;
void add_edge(int a,int b,int w)
{
edge[E].v = b;
edge[E].w = w;
edge[E].next = head[a];
head[a] = E++;
}
int head[maxn];
bool Del[maxn];
int N , K;
int size[maxn] , opt[maxn];
int tnode[maxn] , tns;
int all[maxn] , as;
void Dfs(int u,int f)
{
tnode[tns++] = u;
size[u] = 1;
opt[u] = 0;
for(int i=head[u];~i;i=edge[i].next) {
int v = edge[i].v;
if(!Del[v] && v != f) {
Dfs(v,u);
size[u] += size[v];
opt[u] = max(opt[u],size[v]);
}
}
}
int Get_Root(int u)
{
tns = 0;
Dfs(u,-1);
int mi = maxn , ans = -1;
for(int i = 0; i < tns; i++){
opt[tnode[i]] = max(opt[tnode[i]],size[u]-size[tnode[i]]) ;
if(opt[tnode[i]] < mi) {
mi = opt[tnode[i]];
ans = tnode[i];
}
}
return ans;
}
void Get_Dis(int u,int len,int fa)
{
all[as++] = len;
for(int i=head[u];~i;i=edge[i].next){
int v = edge[i].v;
if(!Del[v] && v != fa) {
Get_Dis(v,len+edge[i].w,u);
}
}
}
void Solve(int u)
{
u = Get_Root(u);
int nch = 0;
Ans += Calc(u,0,true);
Del[u] = true;
for(int i=head[u];~i;i=edge[i].next) {
int v = edge[i].v;
if(!Del[v]) {
Ans -= Calc(v,edge[i].w,false);
Solve(v);
}
}
}
inline long long Calc(int u,int w,bool f)
{
int pt = 0 ;
long long sum = 0 ;
as = 0;
Get_Dis(u,w,-1);
sort(all,all+as);
if(f) for(int i = 0; i < as; i++) if(all[i]==K) sum++;//单个点到根
int i = all[0] ? 0 : 1, j = as - 1;
while(i < j) //一对点
{
if(all[i] + all[j] < K) i++;
else if(all[i] + all[j] > K) j--;
else
{
if(all[i] == all[j])
{
sum += (j - i) * (j - i + 1) / 2;
break;
}
int st = i, ed = j;
while(all[st] == all[i]) st++;
while(all[ed] == all[j]) ed--;
sum += (st - i) * (j - ed);
i = st, j = ed;
}
}
return sum;
}
void Ini()
{
int a,b,c;
fill(head,head+N+1,-1);
E = 0;
for(int i = 1; i <= N; i++)
{
while(scanf("%d",&a)!=EOF && a)
{
scanf("%d",&b);
add_edge(i,a,b);
add_edge(a,i,b);
}
}
while(scanf("%d",&K)!=EOF && K)
{
Ans = 0;
fill(Del,Del+N+1,false);
Solve(1);
if(Ans) printf("AYE\n");
else printf("NAY\n");
}
printf(".\n");
}
long long Ans;
}sol;
int main()
{
while(scanf("%d",&sol.N)!=EOF && sol.N)
{
sol.Ini();
}
return 0;
}
/*
7
1 2 3
1 3 1
2 4 3
2 5 3
3 6 1
3 7 3
2
*/