Prim算法
Prim算法可以求最小生成树
1.将所有距离初始化为正无穷
2.进行迭代,找到不在集合中的距离最小的点
集合是指当前的生成树(连通块)
3.更新其他点到集合的最小距离
4.加到集合中去
样例:求最小生成树
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含三个整数 u,v,w,w表示点 u 和点 v 之间存在一条权值为 w 的边。
4 5 1 2 1 1 3 2 1 4 3 2 3 2 3 4 4
//g储存边的权值
//dist是生成树距离
//st判重数组
int prim()
{
memset(dist,0x3f,sizeof dist);
int res=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
}
if(i&&dist[t]==INF)
return INF;
if(i)
res+=dist[t];
st[t]=true;
for(int j=1;j<=n;j++)
{
dist[j]=min(dist[j],g[t][j]);
}
}
return res;
}
Kruskal算法
1.将所有边按权值从小到大排序
2.按顺序枚举每条边,如果不连通,就加到集合中 ,用并查集来表示集合
int Kruskal()
{
sort(edges,edges+m);//边集
for(int i=1;i<=n;i++)
p[i]=i;//初始化并查集
int res=0,cnt=0;
for(int i=0;i<m;i++)
{
int a=edges[i].a;
int b=edges[i].b;
int w=edges[i].w;
a=find(a);
b=find(b);
if(a!=b)//这个边没被加入
{
//加入这条边
p[a]=b;
res=res+w;
cnt++;
}
}
if(cnt<n-1)
return INF;
return res;
}