[bzoj 1468] Tree
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1468
Tree
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1517 Solved: 812
[Submit][Status][Discuss]
Description
给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K
Input
N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k
Output
一行,有多少对点之间的距离小于等于k
Sample Input
7
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
Sample Output
5
点分治裸题,和poj上的不一样,不一样!!!
1 #include<cstdio> 2 #include<cctype> 3 #include<cstring> 4 #include<algorithm> 5 #define gc() getchar() 6 #define max(a,b) ((a)>(b)?(a):(b)) 7 using namespace std; 8 int read() 9 { 10 int rt=0,fl=1;char ch=gc(); 11 while(!isdigit(ch)){if(ch=='-')fl=-1;ch=gc();} 12 while(isdigit(ch)){rt=rt*10+ch-'0';ch=gc();} 13 return rt*fl; 14 } 15 16 const int MAXN = 100005; 17 18 int h[MAXN],nx[MAXN<<1],to[MAXN<<1],val[MAXN<<1],cnt; 19 int son[MAXN],f[MAXN],d[MAXN],deep[MAXN],root,sum,n,k,ans; 20 bool vis[MAXN]; 21 22 void add_edge(int _u,int _v,int _c) 23 { 24 to[++cnt]=_v; 25 nx[cnt]=h[_u]; 26 h[_u]=cnt; 27 val[cnt]=_c; 28 } 29 30 void link(int _u,int _v,int _c) 31 { 32 add_edge(_u,_v,_c); 33 add_edge(_v,_u,_c); 34 } 35 36 void clear() 37 { 38 memset(h,0,sizeof(h)); 39 memset(vis,0,sizeof(vis)); 40 cnt=0; 41 ans = root = 0; 42 } 43 44 void getRoot(int rt,int fa) 45 { 46 son[rt]=1; 47 f[rt]=0; 48 for(int i=h[rt];i;i=nx[i]) 49 { 50 if(to[i]==fa || vis[to[i]]==1)continue; 51 getRoot(to[i],rt); 52 son[rt] += son[to[i]]; 53 f[rt] = max(f[rt],son[to[i]]); 54 } 55 f[rt] = max(f[rt],sum - son[rt]); 56 if(f[rt] < f[root]) root = rt; 57 } 58 59 void getDeep(int rt,int fa) 60 { 61 deep[++deep[0]] = d[rt]; 62 for(int i=h[rt];i;i=nx[i]) 63 { 64 if(to[i]==fa || vis[to[i]]==1)continue; 65 d[to[i]] = d[rt] + val[i]; 66 getDeep(to[i],rt); 67 } 68 } 69 70 int cal(int x,int now) 71 { 72 d[x] = now; 73 deep[0] = 0; 74 getDeep(x,0); 75 sort(deep+1,deep+deep[0]+1); 76 int t = 0,l,r; 77 for(l=1,r=deep[0];l<r;) 78 { 79 if(deep[l] + deep[r] <= k) 80 { 81 t+=r-l; 82 l++; 83 } 84 else r--; 85 } 86 return t; 87 } 88 void work(int rt) 89 { 90 ans += cal(rt,0); 91 vis[rt] = 1; 92 for(int i=h[rt];i;i=nx[i]) 93 { 94 if(vis[to[i]]==1) continue; 95 ans -= cal(to[i],val[i]); 96 sum = son[to[i]]; 97 root = 0; 98 getRoot(to[i],root); 99 work(root); 100 } 101 } 102 int main() 103 { 104 n=read(); 105 for(int i=1;i<n;i++) 106 { 107 int a,b,c; 108 a=read(); 109 b=read(); 110 c=read(); 111 link(a,b,c); 112 } 113 k=read(); 114 sum = n; 115 f[0] = 0x3f3f3f3f; 116 getRoot(1,0); 117 work(root); 118 printf("%d\n",ans); 119 return 0; 120 }