Time Limit: 1 Sec Memory Limit: 30 MB
Submit: 13 Solved: 9
[Submit][Status][Web Board]
Description
Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
给定一个带权树N个结点(1<=N<=10000),定义dist(u,v)为u,v两个点间的最
短路径长度,路径长度定义为路径上所有边的权和。再给定一个K(1<=K<=10^9)
如果对于不同的两个结点a,b.如果满足dist(a,b)<=K,则称其为合法点对,求
有多少合法点对
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
给定一个带权树N个结点(1<=N<=10000),定义dist(u,v)为u,v两个点间的最
短路径长度,路径长度定义为路径上所有边的权和。再给定一个K(1<=K<=10^9)
如果对于不同的两个结点a,b.如果满足dist(a,b)<=K,则称其为合法点对,求
有多少合法点对
Input
The input contains several test cases.
The first line of each test case contains two integers n, k. (n<=10000)
The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.
The first line of each test case contains two integers n, k. (n<=10000)
The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.
Output
For each test case output the answer on a single line.
Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
Sample Output
8
HINT
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct my{
int next,v,w;
};
int read()
{
int p,data=0;
char ch=0;
while ((ch!='-') && ch<'0' || ch>'9') ch=getchar();
if (ch=='-')
{
p=-1;
ch=getchar();
} else p=1;
while (ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
return data*p;
}
const int maxn=10000+10;
my bian[maxn*2];
int adj[maxn],fa,n,k,root=0,son[maxn],minn=(1<<30),dis[maxn*10],tot,sum;
bool done[maxn];
void myinsert(int u,int v,int w){
bian[++fa].v=v;
bian[fa].w=w;
bian[fa].next=adj[u];
adj[u]=fa;
}
void dfs(int x,int fa){
int pp=0;
son[x]=1;
for (int i=adj[x];i;i=bian[i].next){
int v=bian[i].v;
if(v==fa||done[v]) continue;
dfs(v,x);
son[x]+=son[v];
pp=max(pp,son[v]);
}
pp=max(pp,sum-son[x]);//ÁíÍâÒ»´ó¿ÅÊ÷
if(pp<minn) {
minn=pp,root=x;
}
}
void dfs2(int x,int d,int fa){
dis[++tot]=d;
for (int i=adj[x];i;i=bian[i].next){
int v=bian[i].v;
if(!done[v]&&v!=fa){
dfs2(v,d+bian[i].w,x);
}
}
}
int calc(int x,int d){
tot=0;
int ans=0;
dfs2(x,d,0);
sort(dis+1,dis+1+tot);
int i=1,j=tot;
for (;i<j;i++){
while(dis[i]+dis[j]>k && i<j) j--;
ans+=j-i;
}
return ans;
}
int work(int x){
minn=(1<<30);
dfs(x,0);
done[root]=true;
int ans=0;
ans+=calc(root,0);
for (int i=adj[root];i;i=bian[i].next){
int v=bian[i].v;
if(done[v]) continue;
sum=son[v];
ans-=calc(v,bian[i].w);
ans+=work(v);
}
return ans;
}
int main(){
int u,v,w;
while(scanf("%d%d",&n,&k)&&k+n){
memset(bian,0,sizeof(bian));
memset(adj,0,sizeof(adj));
memset(done,false,sizeof(done));
fa=0;
for (int i=1;i<n;i++){
u=read();
v=read();
w=read();
myinsert(u,v,w);
myinsert(v,u,w);
}
sum=n;
printf("%d
",work(1));
}
return 0;
}