社区讨论

警钟掘烂(最唐错误)

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 条回复,欢迎继续交流。

正在加载回复...