80pts,后两点TLE,求调
查看原帖
80pts,后两点TLE,求调
1396080
yh2023zlh楼主2024/12/15 19:36
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=6e5+7;
struct node{
	int l;
	int r;
	int c;
	int fa;
	int fa_0;
}t[N];
vector<pair<int,pair<int,int> > > g;
int n,m,u,v,w,idx,head[N],ans;
int q,fa[N][25],lg[N],dep[N];
bool vis[N];
void add(int u,int v,int w){
	g.push_back({w,{u,v}});
}
void add_node(int u,int v,int w){
	++idx;
	t[idx].c=w,t[idx].fa=idx,t[idx].fa_0=idx;
	t[idx].l=u,t[idx].r=v,t[u].fa_0=idx,t[v].fa_0=idx;
	t[u].fa=idx,t[v].fa=idx;
}
int find(int x){
	if(t[x].fa==x) return x;
	return t[x].fa=find(t[x].fa);
}
void dfs(int d,int x){
	if(x==0) return;
	dep[x]=d,vis[x]=1;
	dfs(d+1,t[x].l),dfs(d+1,t[x].r);
}
int lca(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	while(dep[u]>dep[v]) u=fa[u][lg[dep[v]-dep[u]]];
	if(u==v) return t[u].c;
	int h=lg[idx];
	while(h>=0){
		if(fa[u][h]!=fa[v][h]) u=fa[u][h],v=fa[v][h];
		h--;
	}
	return t[fa[u][0]].c;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w),add(v,u,w);
	}
	sort(g.begin(),g.end());//kruskal   nlogn
	for(int i=1;i<=n;i++) t[i].fa=i;//并查集  n
	idx=n;
	for(int i=0;i<g.size();i++){
		u=g[i].second.first,v=g[i].second.second;
		if(find(u)==find(v)) continue;
		add_node(find(u),find(v),g[i].first);//建树   2n
	}
	for(int i=1;i<=idx;i++){
		fa[i][0]=t[i].fa_0;
		if(i>1) lg[i]=lg[i/2]+1;
	}
	for(int i=1;i<=lg[idx];i++) for(int j=1;j<=idx;j++) fa[j][i]=fa[fa[j][i-1]][i-1];//找爸爸nlogn
	for(int i=1;i<=n;i++){
		if(!vis[find(i)]) dfs(1,find(i));//深度搜索   2n
	}
	scanf("%d",&q);
	while(q--){
		scanf("%d%d",&u,&v);
		if(t[u].fa!=t[v].fa) cout<<"impossible\n";
		else cout<<lca(u,v)<<endl;//lca  nlogn
	}
	return 0;
}
2024/12/15 19:36
加载中...