版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
点分治
例题
ciel the commander
题解:
让你给一个树每个点用小写字母标号, 要求每两个相同的标号之间的路径上至少有一个标号比他们大的点。
甚至算不上点分治,但是可以练习一下点分的求重心。
考虑贪心,每次找一个点标当前最高的号,然后一棵树分成了几棵子树,子树之间的路径肯定会经过当前标号的点,就不需要考虑了,那么递归下去就好了。
然后假如每次对于一棵子树选他的重心标号,最多只需要 个标号就好了。
Tree
来源:poj 1741
题解:
一棵树,求有多少组点对,距离不超过k。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
void chkMax(int &x, int y){if (x < y) x = y;}
void chkMin(int &x, int y){if (x > y) x = y;}
const int N = 1e4+10;
const int M = N<<1;
const int inf = 1e9+7;
struct G{
int h[N], e, nxt[M], v[M], w[M];
void clear(){
memset(h, 0, sizeof(h));
e = 1;
}
void add_dir(int _u, int _v, int _w){
++ e;
nxt[e] = h[_u];
v[e] = _v;
w[e] = _w;
h[_u] = e;
}
void add_undir(int _u, int _v, int _w){
add_dir(_u, _v, _w);
add_dir(_v, _u, _w);
}
}g;
int n, k, ans;
int sz[N], zx, mx, siz;
int l, r, q[N], dpt[N];
bool vis[N];
void dfs2(int u, int fa)
{
q[++ r] = dpt[u];
for (int i = g.h[u]; i; i = g.nxt[i]){
int v = g.v[i];
int w = g.w[i];
if (v == fa || vis[v]) continue;
dpt[v] = dpt[u]+w;
dfs2(v, u);
}
}
int calc(int u, int val)
{
int ret = 0;
l = 1; r = 0; dpt[u] = val;
dfs2(u, 0);
sort(q+1, q+r+1);
while (l < r){
if (q[l]+q[r] <= k) ret += r-l, ++ l;
else -- r;
}
return ret;
}
void get_zx(int u, int fa)
{
sz[u] = 1;
int tmp = 0;
for (int i = g.h[u]; i; i = g.nxt[i]){
int v = g.v[i];
if (v == fa || vis[v]) continue;
get_zx(v, u);
chkMax(tmp, sz[v]);
sz[u] += sz[v];
}
chkMax(tmp, siz-sz[u]);
if (tmp < mx) mx = tmp, zx = u;
}
void dfs1(int u)
{
vis[u] = 1;
ans += calc(u, 0);
for (int i = g.h[u]; i; i = g.nxt[i]){
int v = g.v[i];
int w = g.w[i];
if (vis[v]) continue;
siz = sz[v]; mx = inf;
ans -= calc(v, w);
get_zx(v, u);
dfs1(zx);
}
}
int main()
{
while(scanf("%d%d", &n, &k) && n && k){
g.clear();
ans = 0;
for (int i = 1; i < n; ++ i){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
g.add_undir(x, y, z);
}
memset(vis, 0, sizeof(vis));
siz = n; mx = inf;
get_zx(1, 0);
dfs1(zx);
printf("%d\n", ans);
}
return 0;
}
最短路径树问题
来源:bzoj4016
重建计划
动态点分治
例题
[ZJOI2007]捉迷藏
板子题。
题解链接在这里:my solution