Tree
Time Limit: 1000MS
Memory Limit: 30000K
Total Submissions: 20124
Accepted: 6613
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.
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.
Output
For each test case output the answer on a single line.
Sample Input
Sample Output
Source
IOI论文下载
#include<cstdio>
#include <cstring>
#include <algorithm>
#define m(x) memset(x,0,sizeof x)
using namespace std;
int read(){
int x=0 ,f=1 ;char ch=getchar();
while (ch<' 0 ' ||ch>' 9 ' ) ch=getchar();
while (ch>=' 0 ' &&ch<=' 9 ' ){x=x*10 +ch-' 0 ' ;ch=getchar();}
return x;
}
const int N=1e4+10 ;
struct node{
int v,w,next;
}e[N <<1 ];
int n,K,tot,root,sum,ans,head[N],son[N],f[N],d[N],dep[N];
bool vis[N];
void add(int x,int y,int z){
e[ ++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
e[ ++tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
}
void get_root(int x,int fa){// 寻找重心
// 重心,就是删掉此结点后,剩下的结点最多的树结点个数最小
son[x]=1 ;f[x]=0 ;
for (int i=head[x],v;i;i=e[i].next){
if ((v=e[i].v)==fa||vis[v]) continue ;
get_root(v,x);
son[x] +=son[v];
f[x] =max(f[x],son[v]);
}
f[x] =max(f[x],sum-son[x]);
if (f[x]<f[root]) root=x;
}
void get_deep(int x,int fa){
dep[ ++dep[0 ]]=d[x];
for (int i=head[x],v;i;i=e[i].next){
if ((v=e[i].v)==fa||vis[v]) continue ;
d[v] =d[x]+e[i].w;
get_deep(v,x);
}
}
int calc(int x,int now){
d[x] =now;dep[0 ]=0 ;
get_deep(x, 0 );
sort(dep +1 ,dep+dep[0 ]+1 );
int t=0 ,l,r;
for (l=1 ,r=dep[0 ];l<r;){
if (dep[l]+dep[r]<=K){t+=r-l;l++;}
else r--;
}
return t;
}
void work(int x){// 分治
ans+=calc(x,0 );
vis[x] =1 ;
for (int i=head[x],v;i;i=e[i].next){
if (vis[v=e[i].v]) continue ;
ans -=calc(v,e[i].w);
sum =son[v];
get_root(v,root =0 );
work(root);
}
}
void Cl(){
ans =0 ;tot=0 ;root=0 ;
m(head);m(vis);
}
int main(){
while (Cl(),n=read(),K=read()){
for (int i=1 ,x,y,z;i<n;i++) x=read(),y=read(),z=read(),add(x,y,z);
sum =n;f[0 ]=0x7fffffff ;
get_root( 1 ,0 );
work(root);
printf( " %d\n " ,ans);
}
return 0 ;
}
UPD.2017-05-05
#include<cstdio>
#include <cstring>
#include <algorithm>
#define m(s) memset(s,0,sizeof s);
using namespace std;
template <typename T>
inline void read(T &x){
register char ch=getchar();x=0 ;
while (ch<' 0 ' ||ch>' 9 ' ) ch=getchar();
while (ch>=' 0 ' &&ch<=' 9 ' ) x=x*10 +ch-' 0 ' ,ch=getchar();
}
const int N=1e4+5 ;
int n,k,ans,sum,root;
int siz[N],f[N],d[N],dep[N];bool vis[N];
struct edge{int v,w,next;}e[N<<1 ];int tot,head[N];
inline void add(int x,int y,int z){
e[ ++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
e[ ++tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
}
void findroot(int x,int fa){
siz[x] =1 ;f[x]=0 ;
for (int i=head[x];i;i=e[i].next){
if (e[i].v==fa||vis[e[i].v]) continue ;
findroot(e[i].v,x);
siz[x] +=siz[e[i].v];
f[x] =max(f[x],siz[e[i].v]);
}
f[x] =max(f[x],sum-siz[x]);
if (f[x]<f[root]) root=x;
}
void getdep(int x,int fa){
dep[ ++dep[0 ]]=d[x];
for (int i=head[x];i;i=e[i].next){
if (e[i].v==fa||vis[e[i].v]) continue ;
d[e[i].v] =d[x]+e[i].w;
getdep(e[i].v,x);
}
}
inline int calc(int x,int w){
d[x] =w;dep[0 ]=0 ;getdep(x,0 );
stable_sort(dep +1 ,dep+dep[0 ]+1 );
int res=0 ;
for (int l=1 ,r=dep[0 ];l<r;) if (dep[l]+dep[r]<=k) res+=r-l++;else r--;
return res;
}
void solve(int x){
ans +=calc(x,0 );
vis[x] =1 ;
for (int i=head[x];i;i=e[i].next){
if (vis[e[i].v]) continue ;
ans -=calc(e[i].v,e[i].w);
f[root =0 ]=sum=siz[e[i].v];
findroot(e[i].v, 0 );
solve(root);
}
}
inline void clr(){
tot =0 ;m(head);m(vis);
}
int main(){
for (read(n),read(k);n&&k;read(n),read(k),clr()){
for (int i=1 ,x,y,z;i<n;i++) read(x),read(y),read(z),add(x,y,z);
f[root =0 ]=sum=n;findroot(1 ,0 );
ans =0 ;solve(root);
printf( " %d\n " ,ans);
}
return 0 ;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术