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.
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.
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
Source
LouTiancheng@POJ
题意:给定一颗带边权的树,问数上距离不超过k的不同点对有多少个。
分析:树的点分治,所有树上的路径要么经过根节点要么属于一颗子树,我们处理出经过根节点的值,然后对所有子树递归处理,每次选择重心作为根的话最多走log(n)层,每层log(n)*n的排序复杂度,总复杂度n*log(n)*log(n)。
题意:给定一颗带边权的树,问数上距离不超过k的不同点对有多少个。
分析:树的点分治,所有树上的路径要么经过根节点要么属于一颗子树,我们处理出经过根节点的值,然后对所有子树递归处理,每次选择重心作为根的话最多走log(n)层,每层log(n)*n的排序复杂度,总复杂度n*log(n)*log(n)。
#include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> #define INF 0x3f3f3f3f #define eps 1e-9 #define MOD 1000000007 #define MAXN 10005 using namespace std; typedef long long ll; typedef pair<int,int> pii; vector<pii> G[MAXN]; vector<int> b; int n,k,ans,root,size[MAXN]; bool jud[MAXN]; int dfs(int u,int fa,int tot) { bool flag = true; size[u] = 1; for(int i = 0;i < G[u].size();i++) { pii vv = G[u][i]; if(vv.first != fa && !jud[vv.first]) { int v = vv.first; int tmp = dfs(v,u,tot); if(tmp) return tmp; size[u] += size[v]; if(size[v] > tot/2 ) flag = false; } } if(tot - size[u] > tot/2) flag = false; return flag ? u : 0; } int got_size(int u,int fa) { int num = 1; for(int i = 0;i < G[u].size();i++) { pii vv = G[u][i]; if(vv.first != fa && !jud[vv.first]) num += got_size(vv.first,u); } return num; } void dfs2(int u,int fa,int deep) { b.push_back(deep); for(int i = 0;i < G[u].size();i++) { pii vv = G[u][i]; if(vv.first != fa && !jud[vv.first]) dfs2(vv.first,u,deep+vv.second); } } void deal(int u,int deep,int x) { b.clear(); dfs2(u,-1,deep); sort(b.begin(),b.end()); int tot = 0,sum = b.size(),r = -1; for(int i = sum-1;i;i--) { while(b[i] + b[r+1] <= k && r+1 < i) r++; if(i == r) r--; tot += r+1; } ans += tot*x; } void calc(int u) { deal(u,0,1); jud[u] = true; for(int i = 0;i < G[u].size();i++) { pii vv = G[u][i]; if(!jud[vv.first]) { int v = vv.first; deal(v,vv.second,-1); int root = dfs(v,u,got_size(v,u)); calc(root); } } } int main() { while(scanf("%d%d",&n,&k) && n+k) { ans = 0; memset(jud,0,sizeof(jud)); for(int i = 1;i <= n;i++) G[i].clear(); for(int i = 1;i < n;i++) { int u,v,val; scanf("%d%d%d",&u,&v,&val); G[u].push_back(make_pair(v,val)); G[v].push_back(make_pair(u,val)); } root = dfs(1,0,n); calc(root); cout<<ans<<endl; } }