Compare commits

...

4 Commits

Author SHA1 Message Date
17a58ec2aa docs: 更新README并清理测试代码
更新README添加超时优化方法,同时清理test.cpp中未使用的代码
2025-09-02 15:41:38 +08:00
64a6dc8651 refactor: 移除未使用的cstdio头文件 2025-09-02 12:24:23 +08:00
8f654d7c2d feat(P1967): 添加LCA查询功能并优化图结构处理
实现基于倍增法的LCA查询功能,用于计算图中两点间最小边权
- 添加dpth、fth和cost数组用于存储深度、父节点和路径最小权值
- 新增dfs函数初始化上述数组
- 实现lca函数查询两点间最小边权
- 修改主函数处理查询请求并优化并查集初始化
- 移除调试代码并添加必要头文件
2025-09-02 12:24:08 +08:00
727facbee0 feat: 添加P1967.cpp实现最小生成树算法
实现基于优先队列和并查集的最小生成树算法,用于解决图论中的连通问题。包含边的结构定义、合并操作和结果输出功能。
2025-09-02 11:04:17 +08:00
4 changed files with 145 additions and 18 deletions

0
EOF
View File

View File

@ -14,3 +14,8 @@
1. 编辑距离 i-1,j i,j-1
2. 合并石子 1~k,k+1~i
3. 网捉蛇 1~k用j-1, k+1~i用1
## 超时优化的三种方法
1. 预处理(排序最常用)
2. 二分
3. 数学方法

138
src/9/2/P1967.cpp Normal file
View File

@ -0,0 +1,138 @@
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <ios>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>
using ll = int64_t;
struct Edge{
ll to{};
ll w{};
inline bool operator<(const Edge&r){
return w<r.w;
}
};
struct XYZ{
ll x{},y{},z{};
inline bool operator<(const XYZ&r)const{
return z<r.z;
}
};
const ll maxlog = 15, inf=1e9;
ll n,m,q;
std::vector<std::vector<Edge>> edg;
std::vector<ll> unf, dpth;
std::vector<std::vector<ll>> fth,cost;
std::priority_queue<XYZ> pq;
ll mergednum = 0;
static inline ll find(ll idx){
if(idx==unf[idx])return idx;
return unf[idx]=find(unf[idx]);
}
static inline void merge(ll a,ll b){
unf[find(a)]=find(b);
}
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);
std::cin>>n>>m;
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);
}
while(pq.size() && mergednum < n-1){
auto[x,y,z] = pq.top();
pq.pop();
if(ismerged(x, y))continue;
edg[x].emplace_back(y,z);
edg[y].emplace_back(x,z);
merge(x, y);
mergednum++;
}
// 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';
}
}

View File

@ -1,19 +1,3 @@
#include <cmath>
#include <iostream>
#include <set>
#include <stdexcept>
#include <string>
int main(){
int n;
std::cin>>n;
std::set<int> s;
std::cout<<n<<"\n";
for(int i=1;i<=n;i++){
int tmp;
std::cin>>tmp;
if(s.find(tmp)==s.end()){
throw std::runtime_error(std::to_string(tmp));
}
s.insert(tmp);
}
}