基于倍增的LCA + kruskal重构树 + 并查集

P2245 星际导航

cpp 复制代码
//基于倍增的LCA + kruskal重构树 + 并查集
#include<bits/stdc++.h>
#define endl '\n'
#define rep(_start_,_end_) for(int i =  _start_;i <= (_end_);i ++)
#define all0(x) (x).begin(),(x).end()
#define all1(x) (x).begin() + 1,(x).end()
using namespace std;
using ll = long long;

const int N = 1e5 + 10; // 原图最大顶点数
const int M = 5e5 + 10; // 原图最大边数

int n, m, q;
int par[N * 2];
int val[N * 2];//非叶子的权值
vector<int>trie[N * 2];


struct EDGE
{
	int u, v, w;
};

int Find(int x)
{
	return (par[x] == x) ? x : par[x] = Find(par[x]);
}
int new_node;
void build_kruskal(vector<EDGE>&edge)
{
	//初始化
	for(int i = 1;i <= 2 * n - 1;i ++)
		par[i] = i;
	//遍历所有边
	new_node = n;
	for(auto &[l,r,w] : edge)
	{
		int rootl = Find(l);
		int rootr = Find(r);
		
		if(rootl != rootr)
		{
			new_node ++;
			val[new_node] = w;
//			cout << "newnode: "<<new_node <<endl;
			trie[new_node].push_back(rootl);
			trie[new_node].push_back(rootr);
			
			par[rootl] = new_node;
			par[rootr] = new_node;
		}
	}
}


int dep[N * 2],fa[N * 2][20];

void dfs(int u,int u_father)
{

	dep[u] = dep[u_father] + 1;
	fa[u][0] = u_father;
	
	for(int j = 1;j <= 19;j ++)
	{
		fa[u][j] = fa[fa[u][j - 1]][j - 1];
	}
	
	for(auto v:trie[u])
	{
		if(v != u_father)
		{
			dfs(v,u);
		}
	}
}


int get_lca(int l,int r)
{
	if(dep[l] < dep[r])swap(l,r);
	for(int i = 19;i >= 0;i --)
	{
		if(dep[fa[l][i]] >= dep[r])
			l = fa[l][i];
	}
	
	if(l == r)return l;
	
	for(int i = 19;i >= 0;i --)
	{
		if(fa[l][i] != fa[r][i])
			l = fa[l][i],r = fa[r][i];
	}
	return fa[l][0];
}

void solve()
{
	cin >> n >> m; 
	vector<EDGE> edge(m);
	rep(0, m - 1) cin >> edge[i].u >> edge[i].v >> edge[i].w;
	
	sort(all0(edge), [](const auto&i, const auto&j){
		return i.w < j.w;
	});
	//重构树
	build_kruskal(edge);
	//预处理dfs
	for(int i = 1;i <= new_node ;i ++)
	{
		if(par[i] == i)
		{
			dfs(i,0);
		}
	}
//	for(int i = 1;i <= 2 * n - 1;i ++)cout << fa[i][0]<<" ";
//	cout << endl;
	cin >> q;
	while(q --)
	{
		int l,r;
		cin >> l >> r;
		if(Find(l) != Find(r))
			cout << "impossible"<<endl;
		else{
			cout << val[get_lca(l,r)] <<endl;
		}
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int t;
	// cin >> t;
	t = 1;
	
	while(t --)
	{
		solve();
	}
	return 0;
}
相关推荐
AIHR数智引擎11 天前
KPI物理失效:AI原生组织的效能重构与技能度量
人工智能·经验分享·职场和发展·重构·ai-native·aihr
海砥装备HardAus11 天前
大载重工业无人机动力容错控制:单电机失效下的应急重构算法设计
算法·重构·嵌入式·无人机
夏幻灵11 天前
深度解析 JavaScript 异步编程:从回调地狱到 Promise 的重构
开发语言·javascript·重构
ThornArmor11 天前
【工具篇·番外】跨语言生态的主权回收:基于 ISA 说明书的 4-bit 双向汇编系统全线封顶
c语言·开发语言·汇编·c++·重构·架构
AI焦点11 天前
2026年AI大模型中转横评实测:跨越价格陷阱,重构生产级聚合平台的评估基准
人工智能·重构
极客老王说Agent12 天前
2026全业务链条断层破解:智能体如何重构端到端业务闭环
人工智能·ai·chatgpt·重构
思茂信息12 天前
CST软件基于液态金属开关的方向图可重构天线
服务器·算法·重构·cst·仿真软件·电磁仿真
lili001212 天前
2026 企业 AI 选型新范式:OpenRouter Fusion 证明多模型融合性价比远超单模型,企业该如何重构技术栈? - 微元算力(weytoken)
java·人工智能·python·重构·ai编程
青绿蓝LCA低碳研究院12 天前
环保的本质:从“末端修补”到“系统重构”的生存范式转移 - 蓝色星球
大数据·人工智能·经验分享·重构