萌新刚学OI,求助kruskal
  • 板块P4197 Peaks
  • 楼主bad_kstt
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/2/9 04:12
  • 上次更新2023/11/5 03:31:07
查看原帖
萌新刚学OI,求助kruskal
150435
bad_kstt楼主2021/2/9 04:12

rt,kruskal重构树做这个题目,4个点过了前2个,不大晓得为什么错了
已经调了一个晚上了 , 也找了个神仙的代码对对, 查不出什么幺蛾子
救救孩子/kel

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define repp(i,a,b) for(int i=(a);i<(b);++i)
#define perr(i,a,b) for(int i=(a);i>(b);--i)
#define pb push_back
#define rz resize

typedef long long ll;

const int maxn = 2000010, maxm = 2000010, inf = 0x7f7f7f7f;
int h[maxn], b[maxn], dec[maxn], nn;
struct edge {
    int x, w;
};
std::vector< std::vector<edge> > g;
std::vector< std::vector<int> > kr_tree;
int par[maxn<<1], wei[maxn<<1];
int getpar(int x) { return x == par[x] ? x : par[x] = getpar(par[x]); }
struct node {
    int x, y, w;
} edges[maxm];
void kruskal(int n, int m) {
    kr_tree.clear(); kr_tree.resize(n<<1);
    rep(i,1,n<<1) par[i] = i; rep(i,1,n) wei[i] = 0;
    std::sort(edges + 1, edges + m + 1, [&](node& a, node& b){return a.w < b.w;});
    int tot = n;
    rep(i,1,m) {
        int x = getpar(edges[i].x), y = getpar(edges[i].y);
        if(x == y) continue;
        wei[++tot] = edges[i].w; kr_tree[tot].pb(x);kr_tree[tot].pb(y); par[x] = par[y] = tot;
        if(tot == (n<<1)-1) break;
    }
    wei[0] = inf;
}

int fa[maxn<<1][27], dfn[maxn<<1], idfn[maxn<<1], siz[maxn<<1], dfs_clock = 0;
void dfs(int cur, int pre) {
//    std::cout << "enter dfs:" << cur << ' ' << pre << std::endl;
    dfn[cur] = ++dfs_clock; idfn[dfs_clock] = cur; fa[cur][0] = pre; siz[cur] = 1;
    rep(i,1,25) fa[cur][i] = fa[fa[cur][i-1]][i-1];
    for(int ver : kr_tree[cur]) dfs(ver, cur), siz[cur] += siz[ver];
//    std::cout << "quit dfs:" << cur << ' ' << pre << std::endl;
}

int rt[maxn], ls[30000005], rs[30000005], dat[30000005], tot;
int insert(int prec, int lp, int rp, int x) {
    int p = ++tot;
    if(lp == rp) { ++dat[p]; return p; }
    int mid = (lp + rp) >> 1;
    if(x <= mid) rs[p] = rs[prec], ls[p] = insert(ls[prec], lp, mid, x);
    else ls[p] = ls[prec], rs[p] = insert(rs[prec], mid+1, rp, x);
    dat[p] = dat[ls[p]] + dat[rs[p]]; return p;
}

int kth(int pl, int pr, int lp, int rp, int k) {
    // printf("pl=%d, pr=%d, lp=%d, rp=%d, k=%d, datls=%d, datrs=%d, dat=%d\n", pl, pr, lp, rp, k,  dat[ls[pr]]-dat[ls[pl]], dat[rs[pr]]-dat[rs[pl]], dat[pr]-dat[pl]);
    if(dat[pr] - dat[pl] < k) return -1;
    if(lp == rp) return lp;
    int mid = (lp + rp) >> 1;
    // if(dat[ls[pr]]-dat[ls[pl]] < k) return kth(rs[pl], rs[pr], mid+1, rp, k - dat[ls[pr]] + dat[ls[pl]]);
    // return kth(ls[pl], ls[pr], lp, mid, k);
    if(dat[rs[pr]]-dat[rs[pl]] < k) return kth(ls[pl], ls[pr], lp, mid, k - dat[rs[pr]] + dat[rs[pl]]);
    return kth(rs[pl], rs[pr], mid+1, rp, k);
}

// void debug(int p, int lp, int rp) {
//     if(!p) return;
//     std::cout << p << ' ' << lp << ' ' << rp << ' ' << dat[p] << ' ' << ls[p] << ' ' << rs[p] << std::endl;
//     if(lp == rp) return;
//     int mid = (lp + rp) >> 1;
//     debug(ls[p], lp, mid); debug(rs[p], mid + 1, rp);
// }

int rid[maxn<<1], rclc;
void build(int n) {
    rep(i,1,(n<<1)-1) {
        // std::cout << idfn[i] << ' ';
        if(idfn[i] > n) {rid[i] = rid[i-1]; continue;}
        rid[i] = ++rclc; rt[rclc] = insert(rt[rclc-1], 1, nn, std::lower_bound(b+1,b+nn+1,h[idfn[i]]) - b);
        // std::cout << "building" << i << ' ' << std::lower_bound(b+1, b+nn+1, h[idfn[i]]) - b << std::endl;
        // debug(rt[rclc], 1, nn);
    }
    // puts("");
    // rep(i,1,(n<<1)-1) std::cout << rid[i] << ' '; puts("");
}

int main() {
    if(fopen("yl.in", "r")) {
        freopen("yl.in", "r", stdin);
        freopen("yl.out", "w", stdout);
    }
    int n, m, q, u, v, w;
    std::cin >> n >> m >> q;
    rep(i,1,n) std::cin >> h[i], b[i] = h[i];
    std::sort(b + 1, b + n + 1);
    nn = std::unique(b + 1, b + n + 1) - b - 1;
    g.resize(n + 1);
    rep(i,1,m) {
        std::cin >> u >> v >> w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
        edges[i] = {u, v, w};
    }
    kruskal(n, m);
    // rep(i,1,(n<<1)-1) {
    //   std::cout << i << ' ' << wei[i] << std::endl;
    //   for(int ver : kr_tree[i]) printf("%d ", ver); puts("");
    // }
    dfs((n<<1)-1, 0);
    // rep(i,1,(n<<1)-1) {
    //     rep(j,0,20) std::cout << fa[i][j] << ' ';
    //     puts("");
    // }
    // rep(i,1,n) std::cout << std::lower_bound(b+1,b+nn+1,h[i]) - b << ' '; puts("");
    build(n);
    ls[0] = rs[0] = dat[0] = 0;
    // rep(i,1,rclc) {
    //     std::cout << "#######rep" << i << std::endl;
    //     debug(rt[i], 1, nn);
    // }
    // rep(i,1,(n<<1)-1) std::cout << idfn[i] << ' '; std::cout << std::endl;
    // rep(i,1,(n<<1)-1) std::cout << rid[i] << ' '; std::cout << std::endl;
    // rep(i,1,(n<<1)-1) std::cout << rt[i] << ' '; std::cout << std::endl;
    // rep(i,1,(n<<1)-1) std::cout << wei[i] << ' '; std::cout << std::endl;
    rep(qr,1,q) {
        std::cin >> u >> v >> w;
        // rep(i,0,4) std::cout << fa[u][i] << ' '; puts("");
        per(i,25,0) if(wei[fa[u][i]] <= v) u = fa[u][i];
        // std::cout << u << ' ' << dfn[u] << ' ' << siz[u] << std::endl;
        // std::cout << dat[rt[rid[dfn[u]-1]]] << ' ' << dat[rt[rid[dfn[u]+siz[u]-1]]] << std::endl;
        int t = kth(rt[rid[dfn[u]-1]], rt[rid[dfn[u]+siz[u]-1]], 1, nn, w);
        if(t == -1) printf("-1\n");
        else printf("%d\n", b[t]);
    }
    return 0;
}

2021/2/9 04:12
加载中...