点分治40分tle求助
  • 板块P4178 Tree
  • 楼主MlKE
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/3/16 16:53
  • 上次更新2023/10/28 06:27:19
查看原帖
点分治40分tle求助
492732
MlKE楼主2022/3/16 16:53

RT,https://www.luogu.com.cn/record/71527524

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, k, head[N], Next[N << 1], edge[N << 1], ver[N << 1], idx;
void add(int x, int y, int z)
{
    ver[++idx] = y, edge[idx] = z;
    Next[idx] = head[x], head[x] = idx;
}
int v[N], ans, pos, Ans, sz[N], cnt[N], w[N], tot, a[N], b[N], d[N];
void get_core(int S, int x)
{
    v[x] = 1, sz[x] = 1;
    int max_part = 0;
    for (int i = head[x]; ~i; i = Next[i])
    {
        int y = ver[i];
        if (v[y] || w[y]) continue;
        get_core(S, y);
        sz[x] += sz[y];
        max_part = max(max_part, sz[y]);
    }
    max_part = max(max_part, S - sz[x]);
    if (ans > max_part)
        ans = max_part, pos = x;
}
void get_data(int x)
{
    v[x] = 1;
    for (int i = head[x]; ~i; i = Next[i])
    {
        int y = ver[i];
        if (v[y] || w[y]) continue;
        a[++tot] = y, b[y] = b[x];
        cnt[b[y]]++, d[y] = d[x] + edge[i];
        get_data(y);
    }
}
bool cmp(int x, int y)
{
    return d[x] < d[y];
}
void calc(int S, int x)
{
    memset(v, 0, sizeof(v)), ans = S;
    get_core(S, x);
    memset(cnt, 0, sizeof(cnt));
    memset(d, 0, sizeof(d));
    memset(v, 0, sizeof(v));
    a[tot = 1] = b[pos] = pos;
    cnt[pos] = w[pos] = 1;
    for (int i = head[pos]; ~i; i = Next[i])
    {
        int y = ver[i];
        if (v[y] || w[y]) continue;
        a[++tot] = b[y] = y;
        cnt[y]++, d[y] = edge[i];
        get_data(y);
    }
    sort(a + 1, a + tot + 1, cmp);
    int l = 1, r = tot;
    --cnt[b[a[1]]];
    while (l < r)
    {
        while (d[a[l]] + d[a[r]] > k)
            cnt[b[a[r--]]]--;
        Ans += r - l - cnt[b[a[l]]];
        --cnt[b[a[++l]]];
    }
    for (int i = head[pos]; ~i; i = Next[i])
    {
        int y = ver[i];
        if (w[y]) continue;
        calc(sz[y], y);
    }
}
int main()
{
    memset(head, -1, sizeof(head));
    scanf("%d", &n);
    int u, v, q;
    for (int i = 1; i < n; i++)
    {
        scanf("%d%d%d", &u, &v, &q);
        add(u, v, q), add(v, u, q);
    }
    scanf("%d", &k);
    calc(n, 1);
    printf("%d\n", Ans);
    return 0;
}
2022/3/16 16:53
加载中...