Kruskal重构树+倍增lca求助
查看原帖
Kruskal重构树+倍增lca求助
206423
焚魂楼主2024/10/4 13:48

不知道为什么除了hack数据其他全WA,实在不知道有什么问题qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

int n,m,head[3000010],tot,val[3000010],qq;
int f[3000010][21],dep[3000010];
int father[3000010];
bool vis[300010];
struct node{
    int v,next;
}cnt[3000010];
struct Node{
    int u,v,w;
    bool operator < (const Node &a) const {
        return w < a.w;
    }
};
priority_queue<Node,vector<Node> > q;                       //即用优先队列将每条边权值从大到小排序

void insert(int u,int v) {
    cnt[++tot].next = head[u];
    cnt[tot].v = v;
    head[u] = tot;
}

Node getnode(int u,int v,int w) {
    return Node{u,v,w};
}

int find(int x) {
    if(father[x] != x) father[x] = find(father[x]);
    return father[x];
}

void Deal_first(int u,int fat) {                              //lca预处理
    vis[u] = true;
    dep[u] = dep[fat] + 1;
    for(int i = 0;i <= 19;i++)
        f[u][i+1] = f[f[u][i]][i];
    for(int i = head[u];i;i = cnt[i].next) {
        if(cnt[i].v == fat) continue;
        f[cnt[i].v][0] = u;
        Deal_first(cnt[i].v,u);
    }
}

int lca(int x,int y) {
    if(dep[x] < dep[y]) swap(x,y);
    for(int i = 20;i >= 0;i--) {
        if(dep[f[x][i]] >= dep[y])
            x = f[x][i];
        if(x == y) return x;
    }
    for(int i = 20;i >= 0;i--) {
        if(f[x][i] != f[y][i]) {
            x = f[x][i];
            y = f[y][i];
        }
    }
    return f[x][0];
}

void unionn(int x,int y) {
    x = find(x);
    y = find(y);
    father[y] = x;
}

int main() {
    cin >> n >> m;
    for(int i = 1;i <= 2*n;i++) father[i] = i;
    for(int i = 1;i <= m;i++) {
        int u,v,w;
        cin >> u >> v >> w;
        q.push(getnode(u,v,w));
    }
    int k = n;
    while(!q.empty()) {
        int u = q.top().u;
        int v = q.top().v;
        int w = q.top().w;
        if(find(u) != find(v)) {
            k++;
            unionn(k,u); unionn(k,v);
            insert(k,u); insert(u,k);
            insert(v,k); insert(k,v);
            val[k] = w;
        }
        q.pop();
        if(k == 2*n-1) break;
    }

    for(int i = k;i >= 1;i--) {
        if(!vis[i])
            Deal_first(find(i),0);
    }

    cin >> qq;
    while(qq--) {
        int s,t;
        cin >> s >> t;
        int ans = val[lca(s,t)];
        if(ans != 0)
            cout << ans << "\n";
        else cout << -1 << "\n";
    }

    return 0;
}
2024/10/4 13:48
加载中...