首页 > 代码库 > poj1741(点分治)

poj1741(点分治)

Problem

题目大意

解题分析

参考程序

技术分享
  1 #include <map>  2 #include <set>  3 #include <stack>  4 #include <queue>  5 #include <cmath>  6 #include <ctime>  7 #include <string>  8 #include <vector>  9 #include <cstdio> 10 #include <cstdlib> 11 #include <cstring> 12 #include <cassert> 13 #include <iostream> 14 #include <algorithm> 15 #pragma comment(linker,"/STACK:102400000,102400000") 16 using namespace std; 17  18 #define N 100008     19 #define LL long long 20 #define lson l,m,rt<<1 21 #define rson m+1,r,rt<<1|1  22 #define clr(x,v) memset(x,v,sizeof(x)); 23 #define bitcnt(x) __builtin_popcount(x) 24 #define rep(x,y,z) for (int x=y;x<=z;x++) 25 #define repd(x,y,z) for (int x=y;x>=z;x--) 26 const int mo  = 1000000007; 27 const int inf = 0x3f3f3f3f; 28 const int INF = 2000000000; 29 /**************************************************************************/  30  31 int n,k,sum,tot,root,ans; 32 int lt[N],f[N],vis[N],size[N],a[N]; 33 struct line{int u,v,w,nt;}eg[N*2]; 34 vector <int> vec; 35 void add(int u,int v,int w) 36 { 37     eg[++sum]=(line){u,v,w,lt[u]}; 38     lt[u]=sum; 39 } 40 void init() 41 { 42     clr(lt,0); sum=1; ans=0; 43     clr(f,0); f[0]=INF; 44     clr(vis,0); 45 } 46 void getRoot(int u,int fa) 47 {     48     size[u]=1; f[u]=0; 49     for (int i=lt[u];i;i=eg[i].nt) 50     {     51         int v=eg[i].v; 52         if (vis[v] || v==fa) continue; 53         getRoot(v,u); 54         size[u]+=size[v]; 55         f[u]=max(f[u],size[v]); 56     } 57     f[u]=max(f[u],tot-size[u]); 58     if (f[u]<f[root]) root=u; 59 } 60 void getDeep(int u,int fa) 61 { 62     vec.push_back(a[u]); 63     for (int i=lt[u];i;i=eg[i].nt) 64     { 65         int v=eg[i].v; 66         if (v==fa || vis[v]) continue; 67         a[v]=a[u]+eg[i].w; 68         getDeep(v,u); 69     } 70 } 71 int cal(int u,int key) 72 { 73     a[u]=key; vec.clear(); 74     getDeep(u,0); 75     sort(vec.begin(),vec.end()); 76     int tmp=0,l=0,r=vec.size()-1; 77     while (l<r) 78     { 79         if (vec[l]+vec[r]<=k) 80         { 81             tmp+=r-l; 82             l++; 83         } 84         else r--; 85     } 86     return tmp; 87 } 88 void work(int u) 89 { 90     ans+=cal(u,0); 91     vis[u]=1; 92     for (int i=lt[u];i;i=eg[i].nt) 93     { 94         int v=eg[i].v; 95         if (vis[v]) continue; 96         ans-=cal(v,eg[i].w); 97         tot=size[v]; root=0; 98         getRoot(v,u); 99         work(root);100     }101 }102 int main()103 {104     while (~scanf("%d%d",&n,&k))105     {106         if (n==0) break;107         init();108         rep(i,1,n-1) 109         {110             int u,v,w;111             scanf("%d%d%d",&u,&v,&w);112             add(u,v,w); add(v,u,w);113         }114         tot=n; root=0;115         getRoot(1,0);116         work(root);117         printf("%d\n",ans);118     }119 }
View Code

 

poj1741(点分治)