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; }; inline 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; bool done[maxn]; inline void myinsert(int u,int v,int w){ bian[++fa].v=v; bian[fa].w=w; bian[fa].next=adj[u]; adj[u]=fa; } inline 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,n-son[x]);//ÁíÍâÒ»´ó¿ÅÊ÷ if(pp<minn) { minn=pp,root=x; } } inline 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); } } } inline 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; } inline 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; 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); } printf("%d\n",work(1)); } return 0; }