poj1741Tree
没有思路的话就看看漆子超的论文
//重心 距离 排序 统计 //http://www.2cto.com/kf/201208/149839.html#comment_iframe #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; #define MAXN 10010 int N,K; struct Node{ //邻接表 int v, w; Node(int v_, int w_){ v= v_, w= w_; } }; vector<Node>son[MAXN]; int vis[MAXN]; //标记是否访问过 int num[MAXN]; //num[i]在以i为根的子树中节点的数量 int size_of_n[MAXN]; //删除n之后得到子树中子树节点的最大值 int mi,root; void dfssize(int n, int fa) //处理子树的大小 { num[n] = 1; size_of_n[n] = 0; int len=son[n].size(); for(int i=0;i<len;i++) { int k = son[n][i].v; if(k != fa && !vis[k]) { dfssize(k, n); num[n] += num[k]; if(num[k] > size_of_n[n]) size_of_n[n] = num[k]; } } } void dfsroot(int r, int n, int fa) //求重心 { if(num[r] - num[n] > size_of_n[n]) size_of_n[n] = num[r] - num[n]; if(size_of_n[n] < mi) mi = size_of_n[n], root = n; int len=son[n].size(); for(int i=0;i<len;i++) { int k = son[n][i].v; if(k != fa && !vis[k]) dfsroot(r, k, n); } } int depth[MAXN],S; void dfs_depth(int n,int fa,int dis) { int i,k,len=son[n].size(); depth[++S]=dis; for(i=0;i<len;i++){ k=son[n][i].v; if(!vis[k]&&k!=fa) dfs_depth(k,n,dis+son[n][i].w); } } /* 对depth中的距离排序后算出有多少对数字相加小于K, dis的作用:dis==0时dfs_depth求出的距离都是以n为根并且不限制方向, dis!=0时,假设dis为n到某个儿子的边的长度,那么求出来的所有距离都以这条边为第一步 也就是相当于限定了方向 */ int NUM(int n,int dis){ S=0; dfs_depth(n,-1,dis); sort(depth+1,depth+1+S); int i=1,j=S,ret=0; while(i<j){ while(depth[j]+depth[i]>K&&j>i) j--; ret+=j-i; i++; } return ret; } int dfs_ans(int n){ mi = N; dfssize(n, 0); dfsroot(n, n, 0); int SUM=0; SUM+=NUM(root,0); vis[root]=1; int len=son[root].size(); for(int i=0;i<len;i++){ int k=son[root][i].v; if(vis[k]) continue; SUM-=NUM(k,son[root][i].w); int temp=root;SUM+=dfs_ans(k);root=temp; } return SUM; } int main() { int i,j,k,u,v,l; while(scanf("%d%d",&N,&K),N||K) { for(i=1;i<=N;i++){son[i].clear();} for(i=1;i<=N-1;i++){ scanf("%d%d%d",&u,&v,&l); son[u].push_back(Node(v,l)); son[v].push_back(Node(u,l)); } memset(vis,0,sizeof(vis)); printf("%d\n",dfs_ans(1)); } return 0; } /* 5 4 1 2 3 1 3 1 1 4 2 3 5 1 6 4 1 2 3 1 3 1 1 4 2 3 5 1 3 6 1 3 4 1 2 3 2 3 2 */