社区讨论

请问数组模拟和并查集模拟(Kruskal)有何区别?

P2330[SCOI2005] 繁忙的都市参与者 2已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mhj9dt8d
此快照首次捕获于
2025/11/03 22:52
4 个月前
此快照最后确认于
2025/11/03 22:52
4 个月前
查看原帖
数组模拟:
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
long long n,m,head[305],tot,vis[305],ans;
struct node{
	int from,to,w,nxt;
}e[20005];
inline bool cmp(node x,node y){
	if(x.w==y.w){
		if(x.from==y.from){
			return x.to<y.to;
		}
		return x.from<y.from;
	}
	else{
		return x.w<y.w;
	}
}
inline void add_edge(int u,int v,int w){
	e[++tot].from=u;
	e[tot].to=v;
	e[tot].nxt=head[u];
	head[u]=tot;
	e[tot].w=w;
	return;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		add_edge(u,v,w);
	}
	sort(e+1,e+1+m,cmp);
	int cnt=0,maxx=0;
	for(int i=1;i<=m;i++){
		int u=e[i].from,v=e[i].to,w=e[i].w;
		if(vis[u]&&vis[v]){
			continue;
		}
		vis[u]=1;
		vis[v]=1;
		maxx=max(maxx,w);
		cnt++;
		bool flag=0;
		for(int j=1;j<=n;j++){
			if(!vis[j]){
				flag=1;
			}
		}
		if(!flag){
			break;
		}
	}
	cout<<cnt<<" "<<maxx<<endl;
	return 0;
}
Kruskal(上面的代码套了层并查集)
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
long long n,m,tot,ans;
struct node{
	int from,to,w,nxt;
}e[20005];
inline bool cmp(node x,node y){
	if(x.w==y.w){
		if(x.from==y.from){
			return x.to<y.to;
		}
		return x.from<y.from;
	}
	else{
		return x.w<y.w;
	}
}
inline void add_edge(int u,int v,int w){
	e[++tot].from=u;
	e[tot].to=v;
	e[tot].w=w;
	return;
}
long long fa[305];
inline int find(int x){
	if(x==fa[x]){
		return x;
	}
	return fa[x]=find(fa[x]);
}
inline void merge(int u,int v){
	fa[find(u)]=find(v);
	return;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		add_edge(u,v,w);
	}
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	sort(e+1,e+1+m,cmp);
	int cnt=0,maxx=0;
	for(int i=1;i<=m;i++){
		int u=e[i].from,v=e[i].to,w=e[i].w;
		if(find(u)==find(v)){
			continue;
		}
		merge(u,v);
		maxx=max(maxx,w);
		cnt++;
		bool flag=0;
		int tmp=find(1);
		for(int j=1;j<=n;j++){
			if(find(j)!=tmp){
				flag=1;
			}
		}
		if(!flag){
			break;
		}
	}
	cout<<cnt<<" "<<maxx<<endl;
	return 0;
}
上面 0pts,下面 100pts,感觉逻辑相同,有何区别?

回复

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

正在加载回复...