POJ 1741 Tree(点分治)
点分治...模板题吧..只要理解了,实现并不难,随便搞搞...
---------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#define rep(i, n) for(int i = 0; i < n; ++i)
#define REP(x) for(edge* e = head[x]; e; e = e->next)
#define clr(x, c) memset(x, c, sizeof(x))
using namespace std;
const int maxn = 10000 + 5;
const int inf = 0x7fffffff;
int n, K;
struct edge {
int to, dist;
edge* next;
};
edge* pt;
edge* head[maxn];
edge EDGE[maxn << 1];
inline void init() {
pt = EDGE;
clr(head, 0);
}
inline void add(int u, int v, int d) {
pt->to = v;
pt->dist = d;
pt->next = head[u];
head[u] = pt++;
}
inline void add_edge(int u, int v, int d) {
add(u, v, d);
add(v, u, d);
}
int size[maxn];
bool vis[maxn];
int dp(int x, int fa) {
size[x] = 1;
REP(x) if(!vis[e->to] && e->to != fa)
size[x] += dp(e->to, x);
return size[x];
}
int root, Min;
int node_num;
void dfs(int x, int fa) {
int Max = node_num - size[x];
REP(x) if(fa != e->to && !vis[e->to]) {
Max = max(Max, size[e->to]);
dfs(e->to, x);
}
if(Max < Min)
root = x, Min = Max;
}
void Dfs(int x) {
Min = inf;
node_num = dp(x, -1);
dfs(x, -1);
}
vector<int> d;
void DFS(int x, int fa, int dist) {
d.push_back(dist);
REP(x) if(!vis[e->to] && fa != e->to)
DFS(e->to, x, dist + e->dist);
}
int Count(int x, int dist) {
d.clear();
DFS(x, -1, dist);
sort(d.begin(), d.end());
int ans = 0, l = 0, r = d.size() - 1;
while(l < r) {
while(d[l] + d[r] > K && l < r) r--;
ans += r - l;
l++;
}
return ans;
}
int ANS;
void COUNT(int x) {
Dfs(x);
vis[root] = 1;
ANS += Count(root, 0);
REP(root) if(!vis[e->to])
ANS -= Count(e->to, e->dist), COUNT(e->to);
}
inline void COUNT_init() {
ANS = 0;
clr(vis, 0);
}
void work() {
COUNT_init();
COUNT(0);
cout << ANS << "\n";
}
void Read() {
int u, v, d;
rep(i, n - 1)
scanf("%d%d%d", &u, &v, &d), add_edge(u - 1, v - 1, d);
}
int main() {
// freopen("test.in", "r", stdin);
while(cin >> n >> K) {
if(!n && !K) break;
init();
Read();
work();
}
return 0;
}
----------------------------------------------------------------------
Tree
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 12802 | Accepted: 4079 |
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