树分治(挑战p360)
Posted starve
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树分治(挑战p360)相关的知识,希望对你有一定的参考价值。
poj1741
题:http://poj.org/problem?id=1741
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const ll INF=1e18; int ans=0,tot,maxx,root; const int M=1e4+4; struct node int v,w,nextt; e[M<<1]; int head[M],vis[M],sz[M],maxv[M],num,dis[M],n,k; void addedge(int u,int v,int w) e[tot].v=v; e[tot].w=w; e[tot].nextt=head[u]; head[u]=tot++; void dfssz(int u,int f) sz[u]=1; maxv[u]=0; for(int i=head[u];~i;i=e[i].nextt) int v=e[i].v;//cout<<"!!"<<endl; if(v==f||vis[v]) continue; dfssz(v,u); sz[u]+=sz[v]; maxv[u]=max(maxv[u],sz[v]); void dfsroot(int r,int u,int f) maxv[u]=max(maxv[u],sz[r]-sz[u]); if(maxv[u]<maxx) maxx=maxv[u]; root=u; for(int i=head[u];~i;i=e[i].nextt) int v=e[i].v; if(vis[v]||v==f) continue; dfsroot(r,v,u); void dfsdis(int u,int d,int f) dis[num++]=d; for(int i=head[u];~i;i=e[i].nextt) int v=e[i].v; if(v==f||vis[v]) continue; dfsdis(v,d+e[i].w,u); int cal(int u,int d) int sum=0; num=0; dfsdis(u,d,-1); sort(dis,dis+num); int i=0,j=num-1; while(i<j) while(dis[i]+dis[j]>k&&i<j) j--; sum+=j-i; i++; return sum; void solve(int u) maxx=n; dfssz(u,-1); dfsroot(u,u,-1); ans+=cal(root,0); vis[root]=1; for(int i=head[root];~i;i=e[i].nextt) int v=e[i].v; if(vis[v]) continue; ans-=cal(v,e[i].w); solve(v); int main() while(~scanf("%d%d",&n,&k)&&(n+k)) tot=0,ans=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); for(int i=1;i<n;i++) int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); solve(1); printf("%lld\n",ans); return 0;
以上是关于树分治(挑战p360)的主要内容,如果未能解决你的问题,请参考以下文章