首页 > 代码库 > 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 }
poj1741(点分治)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。