最小生成树算法(krustra+prime)

给你一个图,求让图连通的边权和最小值

krustra算法是基于加边法,将所有边权排序,每次加一条边,将两个点放在同一个集合中。如果新加的点不在同一个集合中,就合并(并查集)

涉及到排序,可以用结构体存节点的信息,之后按边权从小到大排序。随后遍历n条边,判断两个节点是否在一个集合中,不在则加入

int find(int x)
{
  if(x==father[x])
     return x;
else
   return find(father[x]);
}
bool Union_set(int x,int y)
{ 
  int lx=find(x),ly=find(y);
 if(father[lx]==father[ly])
  return 0;
else
{
father[lx]=ly;
return 1;
}
int krustra()
{
for(int i=1;i<=n;i++)
  father[i]=i;
}
sort(edge,edge+n,cmp);
for(int i=1;i<=num;i++)//num为边的总数
{
  int x=edge[i].lx,y=edge[i].ly;
if(union_set(x,y))
  ans+=edge[i].value;
}
return ans;
}

这个问题还可以引申一下,如果只需要将若干个点连通。那么我们在每次做完之后,进行一下判断,判断我们所求的点是否在一个集合中了。(当然可以想象这个时间复杂度会很高)

Prime算法(加点法,从一个点出发找离他最近的点,然后依次中间点进行更新)

for(int i=2;i<=n;i++)
   dfs[i]=inf;
dfs[1]=0;
while(1)
{
int min=inf,pos;
for(int i=1;i<=n;i++)
{
 if(!visit[i]&&min>dfs[i])
  min=dfs[i];pos=i;
}
if(min==inf)
 break;
visit[pos]=1; ans+=min;//边权值累加
for(int j=1;j<=n;j++)
{
if(dfs[j]>edge[pos][j])
  dfs[j]=edge[pos][j];
}
}
return ans;
原文地址:https://www.cnblogs.com/flightless/p/8678439.html