首页 > 其他分享 >最小生成树

最小生成树

时间:2022-10-08 22:36:54浏览次数:45  
标签:prim int memset 最小 ret 生成 edge sizeof

kruskal

1.建立并查集,初始每个点为一个集合。

2.每次找到剩余的最短边加入并查集。


#include<bits/stdc++.h>
using namespace std;
int n,m;
int ans;
int f[100086];
struct ret
{
	int x,y,z;
}edge[100086];
bool cmp(ret a,ret b)
{
	return a.z<b.z;
}
int get(int x)
{
	if(x==f[x]) return x;
	return f[x]=get(f[x]);
}

int main(){
	cin>>n>>m;	
	for(int i=1;i<=m;i++)
	{
		cin>>edge[i].x>>edge[i].y>>edge[i].z;
	}
	sort(edge+1,edge+1+m,cmp);
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=get(edge[i].x);
		int y=get(edge[i].y);
		if(x==y) continue;
		f[x]=y;
		ans+=edge[i].z;
	}
	cout<<ans;
	return 0;
}

prim

1.每次找到距离已知最小树最近的点,标记(加入已知图),并用着一点更新其他点到已知图的距离。

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[100086];
int d[10086];
int v[10086];
void prim()
{
	memset(d,0x3f3f,sizeof(d));
	memset(v,0,sizeof(v));
	d[1]=0;
	for(int i=1;i<n;i++)
	{
		int x=0;
		for(int j=1;j<=n;j++)
			if(!v[j]&&(x==0||d[x]<d[j])) x=j;
		v[x]=1;
		for(int y=1;y<=n;y++)
		{
			if(!v[y]) d[y]=min(d[y],a[x][y]);	
		}	
	}
}
int main(){
	cin>>n>>m;
	memset(a,0x3f3f,sizeof(a));
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		a[x][y]=z;
	}
	prim();
	for(int i=1;i<=n;i++) ans+=d[i];
	cout<<ans;
	return 0;
}

标签:prim,int,memset,最小,ret,生成,edge,sizeof
From: https://www.cnblogs.com/mrkou/p/16770498.html

相关文章