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 <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using ll = int64_t;
|
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<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;
|
std::priority_queue<XYZ> pq;
|
||||||
ll mergednum = 0;
|
ll mergednum = 0;
|
||||||
|
|
||||||
@ -42,6 +46,42 @@ static inline bool ismerged(ll a,ll b){
|
|||||||
return find(a)==find(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(){
|
int main(){
|
||||||
std::ios_base::sync_with_stdio(false);
|
std::ios_base::sync_with_stdio(false);
|
||||||
std::cin.tie(nullptr);
|
std::cin.tie(nullptr);
|
||||||
@ -50,8 +90,15 @@ int main(){
|
|||||||
|
|
||||||
edg.resize(n+1);
|
edg.resize(n+1);
|
||||||
unf.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++){
|
for(ll i=1;i<=n;i++){
|
||||||
|
unf[i]=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(ll i=1;i<=m;i++){
|
||||||
ll x,y,z;
|
ll x,y,z;
|
||||||
std::cin>>x>>y>>z;
|
std::cin>>x>>y>>z;
|
||||||
pq.emplace(x,y,z);
|
pq.emplace(x,y,z);
|
||||||
@ -67,12 +114,26 @@ int main(){
|
|||||||
mergednum++;
|
mergednum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ll u=1;u<=n;u++){
|
// for(ll u=1;u<=n;u++){
|
||||||
for(auto [v,w]:edg[u]){
|
// for(auto [v,w]:edg[u]){
|
||||||
char buff[128];
|
// printf("point %lld to %lld weight %lld\n",u,v,w);
|
||||||
memset(buff, 0, sizeof(buff));
|
// }
|
||||||
sprintf(buff,"point %lld to %lld weight %lld\n",u,v,w);
|
// }
|
||||||
std::cout<<buff;
|
|
||||||
|
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