제출 #1333674

#제출 시각아이디문제언어결과실행 시간메모리
1333674YSH2020Wind Turbines (EGOI25_windturbines)C++20
40 / 100
4094 ms63656 KiB
//we attempt coding lca on kruskal tree for the first time. lets hope it goes ok
//it gone bad. my lca is messed up.
#include <bits/stdc++.h>
using namespace std;



#define int long long
const int MAXN=100005;

struct ufds{
    int par[2*MAXN];
    ufds(int n) {
        for (int i= 0; i < n; i++) par[i]=i;
    }
    int getp(int x) {
        if (par[x]==x) return x;
        else return par[x]=getp(par[x]);
    }
    int join(int x, int y) {
        x = getp(x);
        y = getp(y);
        if (x==y) return 0;
        par[x]=y;
        return 1;
    }
};

vector<int> adj[2*MAXN];
int depth[2*MAXN];
int par[2*MAXN][22];
int preord[2*MAXN];
int weights[2*MAXN];
int ord = 0;
void dfs(int n, int p) {
    par[n][0]=p;
    preord[n]=ord;
    ord++;
    for (auto i:adj[n]) {
        if (i!=p) {
            depth[i]=depth[n]+1;
            dfs(i,n);
        }
    }
}
void build(int N) {
    for (int i = 1; i < 22; i++) {
        for (int j = 0; j < N; j++) {
            par[j][i]=par[par[j][i-1]][i-1];
        }
    }
}

int kpar(int n, int k) {
    for (int i = 0; i < 22; i++) {
        if (k&(1<<i)) n = par[n][i];
    }
    return n;
}

int lca(int x, int y) {
    if (depth[x] < depth[y]) swap(x,y);
    x = kpar(x,depth[x]-depth[y]);
    if (x==y) return x;
    for (int i = 21; i >= 0; i--) {
        if (par[x][i]!=par[y][i]) {
            x = par[x][i];
            y = par[y][i];
        }
    }
    
    return par[x][0];
}

bool comp(int x, int y) {
    return preord[x] < preord[y];
}

signed main() {
    int n,m,q; cin >> n >> m >> q;
    vector<pair<int,pair<int,int>>> edges(m);
    for (int i = 0; i < m; i++) {
        int a,b,c; cin >> a >> b >> c; edges[i]={c,{a,b}};
    }
    sort(edges.begin(), edges.end());
    ufds *root1 = new ufds(n);
    ufds *root2 = new ufds(2*n);
    int idx = n;
    int totalweight = 0;
    for (int i = 0; i < m; i++) {
        int w = edges[i].first;
        int a = edges[i].second.first;
        int b = edges[i].second.second;
        if (root1->join(a,b)) {
            //you can join!
            totalweight += w;
            int kroot1 = root2->getp(a);
            int kroot2 = root2->getp(b);
            adj[kroot1].push_back(idx);
            adj[kroot2].push_back(idx);
            adj[idx].push_back(kroot2);
            adj[idx].push_back(kroot1);
            root2->join(a,idx);
            root2->join(b,idx);
            weights[idx]=w;
            idx++;
        }
    }
    //now you have the kruskal tree built. notice that the root is now going to be idx-1;
    idx--;
    depth[idx]=0;
    dfs(idx,idx);
    build(idx+1);
    while (q--) {
        int x,y; cin >> x >> y;
        vector<int> tmp;
        for (int i = x; i <= y; i++) tmp.push_back(i);
        sort(tmp.begin(), tmp.end(), comp);
        int ans = totalweight;
        for (int i = 1; i < tmp.size(); i++) {
            ans -= weights[lca(tmp[i], tmp[i-1])];
        }
        cout << ans<<'\n';
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...