点分治模板
树上的路径有两种处理方法
一种是拆LCA想办法解决,例如天天爱跑步
另一种就是在重心处统计,这就是点分治
点分治的函数中处理当前节点所在联通块size的时间复杂度必须是O(size)或者O(sizelogsize)
这样点分治的复杂度就可以控制在O(nlogn)和O(nlog2n)
话说为啥不加vis[0]=1就会RE???
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 10010 4 #define INF (1<<30) 5 inline int update(int & a,int b){return a>b? a:a=b;} 6 inline bool isitdigit(char c){ return c<='9'&&c>='0';} 7 inline int read() 8 { 9 register int s,f=1;register char c; 10 while(!isitdigit(c=getchar())) (c=='-')&&(f=-1); 11 for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0'); 12 return s*f; 13 } 14 int n,k; 15 int head[N],to[N*2],next[N*2],val[N*2],tot; 16 int mson[N],size[N],root,vis[N]; 17 int deep[N],cnt,res; 18 inline void add(int f,int t,int v) 19 { 20 to[++tot]=t;val[tot]=v;next[tot]=head[f];head[f]=tot; 21 } 22 void getroot(int i,int f) 23 { 24 mson[i]=0,size[i]=1; 25 for(register int j=head[i];j;j=next[j]) if(to[j]!=f&&!vis[to[j]]) 26 { 27 getroot(to[j],i); 28 update(mson[i],size[to[j]]); 29 size[i]+=size[to[j]]; 30 } 31 } 32 void decideroot(int s,int i,int f) 33 { 34 update(mson[i],size[s]-size[i]); 35 if(mson[root]>=mson[i]) root=i; 36 for(register int j=head[i];j;j=next[j]) if(to[j]!=f&&!vis[to[j]]) 37 decideroot(s,to[j],i); 38 } 39 void getdeep(int i,int f,int d) 40 { 41 deep[++cnt]=d; 42 for(register int j=head[i];j;j=next[j]) if(to[j]!=f&&!vis[to[j]]) 43 getdeep(to[j],i,d+val[j]); 44 } 45 inline int work(int i,int d) 46 { 47 cnt=0; 48 getdeep(i,0,d); 49 //sort(deep+1,deep+cnt+1); 50 sort(deep+1,deep+cnt+1); 51 int s=1,t=cnt,ans=0; 52 while(s<t) 53 { 54 while((s<t)&&(deep[s]+deep[t]>k)) 55 t--; 56 ans+=t-s;s++; 57 } 58 return ans; 59 } 60 void dfs(int i) 61 { 62 root=mson[0]=0; 63 getroot(i,0); 64 mson[0]=INF; 65 decideroot(i,i,0); 66 int ans=work(root,0); 67 vis[root]=1; 68 for(register int j=head[root];j;j=next[j]) if(!vis[to[j]]) 69 ans-=work(to[j],val[j]); 70 res+=ans; 71 for(register int j=head[root];j;j=next[j]) if(!vis[to[j]]) 72 { 73 dfs(to[j]); 74 } 75 } 76 int main() 77 { 78 freopen("poj1741_tree.in","r",stdin); 79 freopen("poj1741_tree.out","w",stdout); 80 while(scanf("%d%d",&n,&k)&&n&&k) 81 { 82 res=0; 83 memset(vis,0,sizeof(vis)); 84 memset(head,0,sizeof(head)); 85 memset(to,0,sizeof(to)); 86 memset(next,0,sizeof(next)); 87 memset(val,0,sizeof(val)); 88 tot=0; 89 vis[0]=1; 90 for(register int i=1;i<n;++i) 91 { 92 int f=read(),t=read(),v=read(); 93 add(f,t,v); 94 add(t,f,v); 95 } 96 dfs(1); 97 printf("%d\n",res); 98 } 99 return 0; 100 }