mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-09-06 02:00:36 +00:00
feat(P1967): 添加LCA查询功能并优化图结构处理
实现基于倍增法的LCA查询功能,用于计算图中两点间最小边权 - 添加dpth、fth和cost数组用于存储深度、父节点和路径最小权值 - 新增dfs函数初始化上述数组 - 实现lca函数查询两点间最小边权 - 修改主函数处理查询请求并优化并查集初始化 - 移除调试代码并添加必要头文件
This commit is contained in:
parent
727facbee0
commit
8f654d7c2d
@ -1,9 +1,11 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using ll = int64_t;
|
||||
@ -23,9 +25,11 @@ struct XYZ{
|
||||
}
|
||||
};
|
||||
|
||||
ll n,m;
|
||||
const ll maxlog = 15, inf=1e9;
|
||||
ll n,m,q;
|
||||
std::vector<std::vector<Edge>> edg;
|
||||
std::vector<ll> unf;
|
||||
std::vector<ll> unf, dpth;
|
||||
std::vector<std::vector<ll>> fth,cost;
|
||||
std::priority_queue<XYZ> pq;
|
||||
ll mergednum = 0;
|
||||
|
||||
@ -42,6 +46,42 @@ static inline bool ismerged(ll a,ll b){
|
||||
return find(a)==find(b);
|
||||
}
|
||||
|
||||
static inline void dfs(ll f,ll cur){
|
||||
dpth[cur]=dpth[f]+1;
|
||||
fth[cur][0]=f;
|
||||
for(ll i=1;i<=maxlog;i++){
|
||||
fth[cur][i]=fth[fth[cur][i-1]][i-1];
|
||||
cost[cur][i]=std::min(cost[fth[cur][i-1]][i-1],cost[cur][i-1]);
|
||||
}
|
||||
for(auto nxt:edg[cur]){
|
||||
if(nxt.to==f)continue;
|
||||
cost[nxt.to][0]=nxt.w;
|
||||
dfs(cur,nxt.to);
|
||||
}
|
||||
}
|
||||
|
||||
static inline ll lca(ll a,ll b){
|
||||
if(dpth[a]>dpth[b])std::swap(a,b);
|
||||
// ll tmp = dpth[b]-dpth[1],ans=0;错误
|
||||
ll tmp = dpth[b]-dpth[a],ans=inf;
|
||||
for(ll j=0;tmp;j++,tmp>>=1){
|
||||
if(tmp&1){
|
||||
ans=std::min(ans,cost[b][j]);
|
||||
b=fth[b][j]; // 注意在if里面
|
||||
}
|
||||
}
|
||||
if(a==b)return ans;
|
||||
for(ll j=maxlog;j>=0 && a!=b;j--){
|
||||
if(fth[a][j]!=fth[b][j]){
|
||||
ans=std::min({ans,cost[a][j],cost[b][j]});
|
||||
a=fth[a][j];
|
||||
b=fth[b][j];
|
||||
}
|
||||
}
|
||||
ans=std::min({ans,cost[a][0],cost[b][0]});
|
||||
return ans;
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
@ -50,8 +90,15 @@ int main(){
|
||||
|
||||
edg.resize(n+1);
|
||||
unf.resize(n+1);
|
||||
fth.resize(n+1,std::vector<ll>(maxlog+1));
|
||||
cost.resize(n+1,std::vector<ll>(maxlog+1,inf));
|
||||
dpth.resize(n+1);
|
||||
|
||||
for(ll i=1;i<=n;i++){
|
||||
unf[i]=i;
|
||||
}
|
||||
|
||||
for(ll i=1;i<=m;i++){
|
||||
ll x,y,z;
|
||||
std::cin>>x>>y>>z;
|
||||
pq.emplace(x,y,z);
|
||||
@ -67,12 +114,26 @@ int main(){
|
||||
mergednum++;
|
||||
}
|
||||
|
||||
for(ll u=1;u<=n;u++){
|
||||
for(auto [v,w]:edg[u]){
|
||||
char buff[128];
|
||||
memset(buff, 0, sizeof(buff));
|
||||
sprintf(buff,"point %lld to %lld weight %lld\n",u,v,w);
|
||||
std::cout<<buff;
|
||||
// for(ll u=1;u<=n;u++){
|
||||
// for(auto [v,w]:edg[u]){
|
||||
// printf("point %lld to %lld weight %lld\n",u,v,w);
|
||||
// }
|
||||
// }
|
||||
|
||||
for(ll i=1;i<=n;i++){
|
||||
if(dpth[i]==0){
|
||||
dpth[0]=0;
|
||||
dfs(0,i);
|
||||
}
|
||||
}
|
||||
std::cin>>q;
|
||||
for(ll i=1;i<=q;i++){
|
||||
ll a,b;
|
||||
std::cin>>a>>b;
|
||||
if (!ismerged(a, b)) {
|
||||
std::cout<<"-1\n";
|
||||
continue;
|
||||
}
|
||||
std::cout<<lca(a,b)<<'\n';
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user