10pts,似乎是爆栈了,求调
查看原帖
10pts,似乎是爆栈了,求调
204926
富乐人呃呃呃楼主2022/3/24 20:59

似乎是在 getDis 处爆的

#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ext/pb_ds/assoc_container.hpp>
#include <iostream>
#include <list>
#include <queue>
#include <random>
#include <set>
#include <vector>

typedef long long ll;

constexpr int MOD = 998244353;
inline int mod(int a)
{
    a %= MOD;
    if (a < 0) a += MOD;
    return a;
};

int canselSync = (std::ios::sync_with_stdio(0),
                  std::cin.tie(0),
                  std::cout.tie(), 0);

constexpr int maxn = 2e5 + 100;
constexpr int maxk = 1e6 + 100;

int n, k;

namespace G
{
struct Edge;
typedef Edge* lpEdge;
struct Edge
{
    int to, w;
    lpEdge nxt;
} e[maxn << 1];
lpEdge head[maxn];
lpEdge cnt = e + 1;
inline void add(int u, int v, int w)
{
    auto tmp = ++cnt;
    tmp->to  = v;
    tmp->w   = w;
    tmp->nxt = head[u];
    head[u]  = tmp;
}

inline void Add(int u, int v, int w)
{
    add(u, v, w), add(v, u, w);
}
} // namespace G

constexpr int INF = 0x3f3f3f3f;
int ans           = INF;

namespace CenDec
{
int tot, ctr;
std::bitset<maxn> del;
int mss[maxn], siz[maxn];
void getCtr(int p, int fa = 0)
{
    siz[p]    = 1;
    auto mssp = mss + p;
    *mssp     = 0;
    for (auto e = G::head[p]; e; e = e->nxt)
        if (!del[p] && e->to != fa)
        {
            getCtr(e->to, p);
            if (ctr != 0) return;
            *mssp = std::max(siz[e->to], *mssp);
            siz[p] += siz[e->to];
        }
    *mssp = std::max(*mssp, tot - siz[p]);
    if (*mssp <= tot / 2)
    {
        ctr     = p;
        siz[fa] = tot - siz[p];
    }
}

int tmp[maxn], dis[maxn], lens[maxn];
void getDis(int p, int len = 1, int fa = 0)
{
    if (dis[p] > k || len > ans) return;
    tmp[++*tmp] = dis[p], lens[*tmp] = len;
    for (auto e = G::head[p]; e; e = e->nxt)
        if (!del[e->to] && e->to != fa)
        {
            dis[e->to] = dis[p] + e->w;
            getDis(e->to, len + 1, p);
        }
}

int minn[maxn], st[maxn];
void preWork(int p)
{
    for (auto e = G::head[p]; e; e = e->nxt)
        if (!del[e->to])
        {
            *tmp       = 0;
            dis[e->to] = e->w;
            getDis(e->to, 1, p);
            for (int j = 1; j <= *tmp; ++j)
                ans = std::min(ans,
                               lens[j] + minn[k - tmp[j]]);
            for (int i = 1; i <= *tmp; ++i)
                minn[st[++*st] = tmp[i]] = std::min(minn[tmp[i]], lens[i]);
        }
    while (*st) minn[st[*st]] = INF, --*st;
}

void sol(int p)
{
    del.set(p);
    minn[0] = 0;
    preWork(p);
    for (auto e = G::head[p]; e; e = e->nxt)
        if (!del[e->to])
        {
            ctr = 0;
            tot = siz[e->to];
            getCtr(e->to, p);
            sol(ctr);
        }
}

} // namespace CenDec

void getData()
{
    std::cin >> n >> k;
    int u, v, w;
    for (int i = 1; i < n; ++i)
    {
        std::cin >> u >> v >> w;
        G::Add(u + 1, v + 1, w);
    }
}

void sol()
{
    using namespace CenDec;
    std::fill(minn, minn + maxn - 1, INF);
    ctr      = 0;
    mss[ctr] = n;
    tot      = n;
    getCtr(1);
    sol(ctr);
    if (ans >= n)
        std::cout << "-1";
    else
        std::cout << ans;
}

signed main()
{
//============================================
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
    int t1 = std::clock();
#endif
    //============================================
    getData();
    sol();
//============================================
#ifndef ONLINE_JUDGE
    int t2 = std::clock();
    std::cout << "\n"
              << (t2 - t1) / double(CLOCKS_PER_SEC) << "s" << std::endl;
#endif
    //============================================
    return 0;
}

2022/3/24 20:59
加载中...