-
Notifications
You must be signed in to change notification settings - Fork 0
/
1741.cpp
119 lines (111 loc) · 2.86 KB
/
1741.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <algorithm>
using namespace std;
#define fromto(from,to,i) for(int (i)=(from);(i)<=(to);++(i))
#define fromgoto(from,to,i) for(int (i)=(from),__size=(to);(i)<=__size;++(i))
#define watch(a,n) for(int __i=0;__i<(n);++__i) printf("%d ",(a)[__i]);printf("\n");
#define MAXN 10008
#define INF INT_MAX/2
typedef pair<int,int> Edge;//v,w
typedef pair<int,int> Zx;//size,u
vector<Edge> G[MAXN];
int subsize[MAXN];
int K;
int G_n;
bool deleted[MAXN];
int consubsize(int u,int p)
{
int sum=1;
fromgoto(0,G[u].size()-1,i) {
int v=G[u][i].first;
if(v==p || deleted[v]) continue;
sum+=consubsize(v,u);
}
return subsize[u]=sum;
}
int tsize;
Zx findzx(int u,int p)
{
Zx res=Zx(INF,0);
int m=-INF;
fromgoto(0,G[u].size()-1,i) {
int v=G[u][i].first,w=G[u][i].second;
if(v==p || deleted[v]) continue;
res=min(res,findzx(v,u));
m=max(m,subsize[v]);
}
res=min(res,Zx(max(m,tsize-subsize[u]),u));
return res;
}
int depth[MAXN];
vector<int> belong[MAXN];
void condb(int u,int p,int b,int d)
{
depth[u]=d;
belong[b].push_back(d);
fromgoto(0,G[u].size()-1,i) {
int v=G[u][i].first,w=G[u][i].second;
if(v==p || deleted[v]) continue;
condb(v,u,b,d+w);
}
}
long long sumxk(vector<int> &arr,int k)
{
//printf("arr_size:%d\n",arr.size());
long long res=0;
sort(arr.begin(),arr.end());
//watch(arr,arr.size());
int h=arr.size()-1;
fromgoto(0,h,i) {
while(h>0 && arr[i]+arr[h]>k) --h;
if(h<=i) break;
res+=h-i;
}
//printf("res=%I64d\n",res);
return res;
}
int solve(int root)
{
if((tsize=consubsize(root,-1))<=1) return 0;
long long ans=0;
root=findzx(root,-1).second;//修正root
belong[root].clear();
belong[root].push_back(0);
fromgoto(0,G[root].size()-1,i) {
int v=G[root][i].first,w=G[root][i].second;
belong[v].clear();
if(!deleted[v]) condb(v,root,v,w);
belong[root].insert(belong[root].end(),belong[v].begin(),belong[v].end());
ans+=sumxk(belong[v],K);
}
ans=sumxk(belong[root],K)-ans;
deleted[root]=true;
fromgoto(0,G[root].size()-1,i) {
int v=G[root][i].first;
if(!deleted[v]) ans+=solve(v);
}
//printf("solve(%d)=%d\n",root,ans);
return ans;
}
int main()
{
while(true) {
scanf("%d%d",&G_n,&K);
if(G_n==0 && K==0) break;
fromto(1,G_n,i) G[i].clear();
memset(deleted,false,sizeof(deleted));
int root;
fromto(1,G_n-1,i) {
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
root=a;
G[a].push_back(Edge(b,w));
G[b].push_back(Edge(a,w));
}
printf("%d\n",solve(root));//因为刚开始是tree,随便选个点为根
}
return 0;
}