跟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;}/*71 2 31 3 12 4 32 5 33 6 13 7 32*/