这是我的代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=10005;
const int M=20005;
int n,k;
int e[M],ne[M],w[M],h[N],tot;
int del[N];
int arr1[N],idx1,arr2[N],idx2;
inline void add(int a,int b,int c) {
e[tot]=b,w[tot]=c,ne[tot]=h[a],h[a]=tot++;
}
inline int get_size(int u,int fa) {
if (del[u]) return 0;
int sz=0;
for (int i=h[u];~i;i=ne[i]) {
if (e[i]==fa) continue;
sz+=get_size(e[i],u);
}
return sz;
}
inline int get_center(int u,int fa,int sz,int& cen) {
if (del[u]) return 0;
int mx=0;
int sum=1;
for (int i=h[u];~i;i=ne[i]) {
if (e[i]==fa) continue;
int k=get_center(e[i],u,sz,cen);
sum+=k;
mx=max(mx,k);
}
mx=max(mx,sz-sum);
if (mx<=sz/2) cen=u;
return sum;
}
inline void get_dis(int u,int fa,int dis,int& idx) {
if (del[u]) return;
arr2[++idx]=dis;
for (int i=h[u];~i;i=ne[i]) {
if (e[i]==fa) continue;
get_dis(e[i],u,dis+w[i],idx);
}
}
bool cmp(const int& a,const int& b) {
return a<b;
}
inline int calc(int* arr,int idx) {
int res=0;
sort(arr+1,arr+1+idx,cmp);
for (int i=0,j=idx;j;--j) {
while (i+1<j && arr[i+1]+arr[j]<=k) i++;
i=min(i,j-1);
res+=i-1;
}
return res;
}
inline int solve(int u) {
if (del[u]) return 0;
get_center(u,0,get_size(u,0),u);
del[u]=true;
int res=0;
idx1=0;
for (int i=h[u];~i;i=ne[i]) {
idx2=0; get_dis(e[i],u,w[i],idx2);
res-=calc(arr2,idx2);
for (int j=1;j<=idx2;++j) {
if (arr2[j]<=k) res++;
arr1[++idx1]=arr2[j];
}
}
res+=calc(arr1,idx1);
for (int i=h[u];~i;i=ne[i]) res+=solve(e[i]);
return res;
}
int main() {
while (scanf("%d %d",&n,&k),n || k) {
for (int i=1;i<=n;++i) del[i]=false,h[i]=-1;
for (int i=1;i<=n-1;++i) {
int a,b,c;
scanf("%d %d %d",&a,&b,&c); a++,b++;
add(a,b,c); add(b,a,c);
}
printf("%d\n",solve(1));
}
return 0;
}
这是另外一份代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010, M = N * 2;
int n, m;
int h[N], e[M], w[M], ne[M], idx;
bool st[N];
int p[N], q[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int get_size(int u, int fa) // 求子树大小
{
if (st[u]) return 0;
int res = 1;
for (int i = h[u]; ~i; i = ne[i])
if (e[i] != fa)
res += get_size(e[i], u);
return res;
}
int get_wc(int u, int fa, int tot, int& wc) // 求重心
{
if (st[u]) return 0;
int sum = 1, ms = 0;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == fa) continue;
int t = get_wc(j, u, tot, wc);
ms = max(ms, t);
sum += t;
}
ms = max(ms, tot - sum);
if (ms <= tot / 2) wc = u;
return sum;
}
void get_dist(int u, int fa, int dist, int& qt)
{
if (st[u]) return;
q[qt ++ ] = dist;
for (int i = h[u]; ~i; i = ne[i])
if (e[i] != fa)
get_dist(e[i], u, dist + w[i], qt);
}
int get(int a[], int k)
{
sort(a, a + k);
int res = 0;
for (int i = k - 1, j = -1; i >= 0; i -- )
{
while (j + 1 < i && a[j + 1] + a[i] <= m) j ++ ;
j = min(j, i - 1);
res += j + 1;
}
return res;
}
int calc(int u)
{
if (st[u]) return 0;
int res = 0;
get_wc(u, -1, get_size(u, -1), u);
st[u] = true; // 删除重心
int pt = 0;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i], qt = 0;
get_dist(j, -1, w[i], qt);
res -= get(q, qt);
for (int k = 0; k < qt; k ++ )
{
if (q[k] <= m) res ++ ;
p[pt ++ ] = q[k];
}
}
res += get(p, pt);
for (int i = h[u]; ~i; i = ne[i]) res += calc(e[i]);
return res;
}
int main()
{
while (scanf("%d%d", &n, &m), n || m)
{
memset(st, 0, sizeof st);
memset(h, -1, sizeof h);
idx = 0;
for (int i = 0; i < n - 1; i ++ )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
printf("%d\n", calc(0));
}
return 0;
}
为什么我这份 TLE 了,他那份 AC 了,我看着好像没啥问题呀。