POJ 1741 Tree
2015-10-24 16:22
267 查看
Tree
Time Limit: 1000msMemory Limit: 30000KB
This problem will be judged on PKU. Original ID: 1741
64-bit integer IO format: %lld Java class name: Main
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
5 4 1 2 3 1 3 1 1 4 2 3 5 1 0 0
Sample Output
8
Source
LouTiancheng@POJ解题:点分治。楼教主的男人八题之一。哥的第一道点分治
哎,太恶心了,不说了
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 100010; struct arc{ int to,w,next; arc(int x = 0,int y = 0,int z = -1){ to = x; w = y; next = z; } }e[maxn<<1]; bool vis[maxn]; int head[maxn],d[maxn],sz[maxn],maxson[maxn],cnt,tot; int n,k; void add(int u,int v,int w){ e[tot] = arc(v,w,head[u]); head[u] = tot++; } void dfs(int u,int fa){ sz[u] = 1; maxson[u] = 0; for(int i = head[u]; ~i; i = e[i].next){ if(e[i].to == fa || vis[e[i].to]) continue; dfs(e[i].to,u); sz[u] += sz[e[i].to]; maxson[u] = max(maxson[u],sz[e[i].to]); } } int FindRoot(int sum,int u,int fa){ int ret = u; for(int i = head[u]; ~i; i = e[i].next){ if(e[i].to == fa || vis[e[i].to]) continue; int x = max(sum - sz[ret],maxson[ret]); int y = FindRoot(sum,e[i].to,u); int z = max(sum - sz[y],maxson[y]); if(z < x) ret = y; } return ret; } void dis(int u,int fa,int depth){ d[cnt++] = depth; for(int i = head[u]; ~i; i = e[i].next){ if(e[i].to == fa || vis[e[i].to] || depth + e[i].w > k) continue; dis(e[i].to,u,depth + e[i].w); } } int calc(int u,int fa,int depth){ int ret = cnt = 0; dis(u,fa,depth); sort(d, d + cnt); int low = 0,high = cnt - 1; while(low < high){ if(d[low] + d[high] <= k) ret += high - low++; else --high; } return ret; } int solve(int u,int fa){ dfs(u,0); int root = FindRoot(sz[u],u,0); vis[root] = true; int ret = calc(root,0,0); for(int i = head[root]; ~i; i = e[i].next){ if(vis[e[i].to]) continue; ret -= calc(e[i].to,root,e[i].w); ret += solve(e[i].to,root); } return ret; } int main(){ int u,v,w; while(scanf("%d%d",&n,&k),n||k){ memset(head,-1,sizeof head); memset(vis,false,sizeof vis); tot = 0; for(int i = 1; i < n; ++i){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } printf("%d\n",solve(1,0)); } return 0; }
View Code
相关文章推荐
- Python 第三方 http 库-Requests 学习
- CSS层叠样式表
- Delphi Randomize
- SQL约束
- Floyd算法
- iOS应用生命周期详解
- Android面试题及答案4
- MonkeyRunner常用方法
- 作为一个有技术背景的你(转载)
- String 中的几个函数的使用方法
- 面试题收集00
- 包装类
- SCN 使用详细介绍
- 一位女性程序员的职业规划
- 京东产品运营手记 | 运营高手在民间
- 后缀名m3u8文件转为一个ts文件---利用word vba
- Acer S3 拆机换固态硬盘!【我的Acer S3小三,时尚时尚最时尚!】
- 概览
- 《设计模式》六大原则之一:接口隔离原则
- android开发 onTouchEvent方法简介