Submission #1333617

#TimeUsernameProblemLanguageResultExecution timeMemory
1333617sporknivesWind Turbines (EGOI25_windturbines)C++20
13 / 100
666 ms61704 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;

int n; 
vector<pii> adj[100004];
int par[100004][25];
int pathmax[100004][25];
int depth[100004];

void dfs(int x, int p, int w) {
	//cout<<x<<" "<<p<<"\n";
	par[x][0]=p;
	pathmax[x][0]=w;
	
	for(pii edge: adj[x]) {
		int i = edge.first, w = edge.second;
		if(i == par[x][0]) continue;
		depth[i] = depth[x] + 1;
		dfs(i, x, w);
	}
}

// return kth parent + max edge on path to kth parent
pii kpar(int x, int k) {
	//int x2 = x;
	int mx=0;
	for(int i=24;i>=0;i--) {
		if(k&(1LL<<i)) {
			mx = max(mx, pathmax[x][i]);
			x = par[x][i];
		}
	}
	//cout<<k<<"th parent of "<<x2<<" is"<<x<<"\n";
	return {x, mx};
}

// return lca + max edge on path between a and b
pii lca(int a, int b) {
	if(depth[a] < depth[b]) swap(a,b);
	pii res = kpar(a, depth[a]-depth[b]);
	a = res.first;
	int mx = res.second;
	if(a == b) return {a, mx};
	for(int i=24;i>=0;i--) {
		if(par[a][i] == par[b][i]) continue;
		mx = max(mx, pathmax[a][i]);
		a = par[a][i];
		mx = max(mx, pathmax[b][i]);
		b = par[b][i];
	}
	
	mx = max(mx, pathmax[a][0]);
	mx = max(mx, pathmax[b][0]);
	return {par[a][0], mx};
}

void init_par() {
	for(int k=1;k<25;k++) {
		for(int i=0;i<n;i++) {
			par[i][k] = par[par[i][k-1]][k-1];
			pathmax[i][k] = max(pathmax[i][k-1], pathmax[par[i][k-1]][k-1]);
		}
	}
}

struct dsu {
	vector<int> par, rnk;
	void init(int n) {
		par.resize(n); for(int i=0;i<n;i++) par[i]=i;
		rnk.resize(n); for(int i=0;i<n;i++) rnk[i]=1;
	}

	int root(int n) {
		if(par[n]==n) return n;
		else par[n] = root(par[n]);
		return par[n];
	}

	void merge(int a, int b) {
		int pa = root(a), pb = root(b);
		if(rnk[pa] >= rnk[pb]) {
			par[pb]=pa;
			if(rnk[pa]==rnk[pb]) rnk[pa]++;
		}
		else {
			par[pa]=pb;
		}
	}

	bool sameSet(int a, int b) {
		return root(a) == root(b);
	}
};

vector<pair<int,pii>> find_mst(vector<pair<int,pii>> edges, vector<int> src) {
	dsu* d = new dsu();
	d -> init(n);
	/*for(int i=0;i<src.size()-1;i++) {
		d -> merge(src[i],src[i+1]);
	}*/
	
	//sort(edges.begin(),edges.end());
	vector<pair<int,pii>> mst;
	int cost=0;
	for(pair<int,pii> x: edges) {
		int w = x.first, a = x.second.first, b = x.second.second;
		if(!(d -> sameSet(a,b))) {
			mst.push_back({w,{a,b}});
			cost+=w;
			d -> merge(a,b);
		}
	}
	
	return mst;
}

signed main() {
	int m,q; cin>>n>>m>>q;
	vector<pair<int,pii>> edges(m);
	for(int i=0;i<m;i++) {
		int a,b,w; cin>>a>>b>>w;
		edges[i] = {w,{a,b}};
	}
	
	sort(edges.begin(),edges.end());
	vector<int> src;
	vector<pair<int,pii>> mst = find_mst(edges,src);
	int cost=0;
	for(pair<int,pii> edge: mst) {
		int w = edge.first;
		cost+=w;
		int a=edge.second.first, b = edge.second.second;
		adj[a].push_back({b,w});
		adj[b].push_back({a,w});
	}
	
	depth[0]=0;
	dfs(0,0,0);
	init_par();
	
	for(int i=0;i<q;i++) {
		int l,r; cin>>l>>r;
		
		cout<<cost-lca(l,r).second<<"\n";
	}
	return 0;
}
#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...