社区讨论

最大生成树+lca 0分求助(

P1967[NOIP 2013 提高组] 货车运输参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo2ox4k8
此快照首次捕获于
2023/10/23 17:23
2 年前
此快照最后确认于
2023/10/23 17:23
2 年前
查看原帖
C
#include<cstdio>
#include<algorithm>
#define inf 999999999
using namespace std;
const int N=1e4+5,M=1e5+5;
inline int read(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=(x<<3)+(x<<1)+c-48;
		c=getchar();
	}
	return x*f;
}
struct edge1{  
    int x,y,dis;
}e1[M];
struct edge2{
    int to,nxt,w;
}e2[M];

int n,m,q,cnt,f[N];
int head[N],dep[N],fa[N][25],w[N][25];
bool vis[N]; 

inline void add_edge(int u,int v,int w){
	cnt++;
    e2[cnt].nxt=head[u];
    e2[cnt].to=v;
    e2[cnt].w=w;
    head[u]=cnt;
}

bool cmp(edge1 a,edge1 b){
	return a.dis>b.dis;
}
 
int find(int x){
	if(x==f[x])return x;
  	return f[x]=find(f[x]);
}

void kruskal(){
	for(int i=1;i<=m;i++){
		int x=find(e1[i].x),y=find(e1[i].y);
		if(x!=y){
            f[x]=y;
            add_edge(e1[i].x,e1[i].y,e1[i].dis);
            add_edge(e1[i].y,e1[i].x,e1[i].dis);
        }
	}
}

inline void dfs(int p){
    vis[p]=1;
    for(int i=head[p];i;i=e2[i].nxt){
        int v=e2[i].to;
        if(vis[v])continue;
        dep[v]=dep[p]+1;
        fa[v][0]=p;
        w[v][0]=e2[i].w;
        dfs(v);
    }
}

int lca(int x,int y){
    int ans=inf;
    if(dep[x]>dep[y])swap(x,y);
    for(int i=20;i>=0;i--)
        if(dep[fa[y][i]]>=dep[x]){
            ans=min(ans,w[y][i]);
            y=fa[y][i];
        }
    if(x==y)return ans;
    for(int i=20;i>=0;i--)
        if(fa[x][i]!=fa[y][i]){
            ans=min(ans,min(w[x][i],w[y][i]));
            x=fa[x][i]; 
            y=fa[y][i];
        }
    ans=min(ans,min(w[x][0],w[y][0]));
    return ans;
}

int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		e1[i].x=read();
        e1[i].y=read();
        e1[i].dis=read();
	}
	sort(e1+1,e1+m+1,cmp);
	for(int i=1;i<=n;i++)f[i]=i;
	kruskal();
	for(int i=1;i<=n;i++){
		if(vis[i])continue;
        dep[i]=1; 
        dfs(i);
        fa[i][0]=i;
        w[i][0]=inf;
	}
	for(int i=1;i<=20;i++)
        for(int j=1;j<=n;j++){
            fa[j][i]=fa[fa[j][i-1]][i-1]; 
            w[j][i]=min(w[j][i-1],w[fa[j][i-1]][i-1]);
        }
	q=read();
	while(q--){
		int x=read(),y=read();
		if(find(x)!=find(y))printf("-1");
		else printf("%d\n",lca(x,y));
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...