社区讨论
警钟掘烂(最唐错误)
P2245星际导航参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhiz8up7
- 此快照首次捕获于
- 2025/11/03 18:08 4 个月前
- 此快照最后确认于
- 2025/11/03 18:08 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=3e5+10;
int n,m,q,fa[N],siz[N],f[N][19],w[N][19],dep[N];
struct node{
int u,v,w;
}g[M];
bool cmp(node x,node y){
return x.w<y.w;
}
struct node2{
int v,w;
};
vector<node2> e[N];
int find(int x){
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x),y=find(y);
if(x==y)return ;
if(siz[x]>siz[y])swap(x,y);
siz[y]+=siz[x];
fa[x]=y;
}
void dfs(int x,int fa){
f[x][0]=fa;
dep[x]=dep[fa]+1;
for(int i=1;i<=18;i++){
f[x][i]=f[f[x][i-1]][i-1];
w[x][i]=max(w[x][i-1],w[f[x][i-1]][i-1]);
}
for(int i=0;i<e[x].size();i++){
int y=e[x][i].v;
if(y==fa)continue;
w[y][0]=e[x][i].w;
dfs(y,x);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int sum=0;
for(int i=0;i<=18;i++){
if((1<<i)&(dep[x]-dep[y])){
sum=max(sum,w[x][i]);
x=f[x][i];
}
}
if(x==y)return sum;
for(int i=18;i>=0;i--){
if(f[x][i]!=f[y][i]){
sum=max(sum,w[x][i]);
sum=max(sum,w[y][i]);
x=f[x][i];
y=f[y][i];
}
}
return max(max(w[x][0],w[y][0]),sum);
}
signed main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
fa[i]=i;
siz[i]=1;
}
for(int i=1;i<=m;i++){
scanf("%d %d %d",&g[i].u,&g[i].v,&g[i].w);
}
sort(g+1,g+m+1,cmp);
for(int i=1;i<=m;i++){
if(find(g[i].u)==find(g[i].v))continue;
merge(g[i].u,g[i].v);
e[g[i].u].push_back({g[i].v,g[i].w});
e[g[i].v].push_back({g[i].u,g[i].w});
}
for(int i=1;i<=n;i++){
if(!dep[i]){
dfs(1,0);
}
}
scanf("%d",&q);
while(q--){
int x,y;
scanf("%d %d",&x,&y);
if(find(x)!=find(y))printf("impossible\n");
else printf("%d\n",lca(x,y));
}
return 0;
}
这会WA前两个点,T最后两个点,原因是dfs的i写成了1。(重构树板子题都能错,不愧是我)。
好hack:https://www.luogu.com.cn/discuss/533288
回复
共 0 条回复,欢迎继续交流。
正在加载回复...