做的第一道找重心然后点分治的题,存下代码。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=10005;
const int inf=0x3fffffff;
struct edge
{
int to,w,next;
}ee[maxn*2];
int e[maxn],ecnt,n,k;
void addedge(int u,int v,int c)
{
ee[ecnt].to=v;ee[ecnt].w=c;ee[ecnt].next=e[u];e[u]=ecnt++;
ee[ecnt].to=u;ee[ecnt].w=c;ee[ecnt].next=e[v];e[v]=ecnt++;
}
int size[maxn],opt[maxn];
vector<int> tnode;
vector<int> all,ch[maxn];
bool del[maxn];
void dfs(int f,int u)
{
tnode.push_back(u);
int i,v;
size[u]=1;opt[u]=0;
for(i=e[u];i!=-1;i=ee[i].next)
{
v=ee[i].to;
if(del[v]||v==f)
continue;
dfs(u,v);
size[u]+=size[v];
opt[u]=max(opt[u],size[v]);
}
}
int find(int u) //找重心
{
tnode.clear();
dfs(-1,u);
int t1,t2,v,i;
t1=inf;
for(i=0;i<tnode.size();++i)
{
v=tnode[i];
opt[v]=max(opt[v],size[u]-size[v]);
if(opt[v]<t1)
{
t1=opt[v];
t2=v;
}
}
return t2;
}
void dfs2(int f,int u,int dep,vector<int> &vec)
{
all.push_back(dep);
vec.push_back(dep);
int v,i;
for(i=e[u];i!=-1;i=ee[i].next)
{
v=ee[i].to;
if(del[v]||v==f)
continue;
dfs2(u,v,dep+ee[i].w,vec);
}
}
ll calc(vector<int> &vec)
{
sort(vec.begin(),vec.end());
ll i,j,d1,d2,ans=0;
int bnd=vec.size();
for(i=0,j=bnd-1;;++i)
{
d1=vec[i];
d2=vec[j];
while(d1+d2>k&&j>=i)
{
j--;
d2=vec[j];
}
if(j<=i)
break;
ans+=j-i;
}
return ans;
}
ll solve(int u)
{
ll i,j,v,ret=0,cnt=0;
u=find(u);
all.clear();all.push_back(0);
for(i=e[u];i!=-1;i=ee[i].next)
{
v=ee[i].to;
if(del[v])
continue;
ch[cnt].clear();
dfs2(u,v,ee[i].w,ch[cnt]);
cnt++;
}
ret=calc(all);
for(i=0;i<cnt;++i)
ret-=calc(ch[i]);
del[u]=true;
for(i=e[u];i!=-1;i=ee[i].next)
{
v=ee[i].to;
if(del[v])
continue;
ret+=solve(v);
}
return ret;
}
int main()
{
int i,u,v,c;
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==0&&k==0)
break;
memset(e,-1,sizeof(e));ecnt=0;
for(i=1;i<n;++i)
{
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
}
memset(del,false,sizeof(del));
printf("%I64d\n",solve(1));
}
return 0;
}