prim算法适合稠密图
kruskal算法适合稀疏图
Prim算法模板
lowcost[i]存储点i和它父亲结点的权值,closest[k]数组记录点k的父亲结点
void Prim(int v)//v为初始点,可以是n个点中的任意一个
{
int i,j,k;
for(i=0;i<n;i++) lowcost[i]=(i==v ? 0 :INF);
for(i=0;i<n;i++)//找出n-1条边
{
int min=INF;//初始化min为一个很大的值
for(j=0;j<n;j++)//从所有为标号结点中,选出lowcost最小的结点k
{
if(lowcost[j]&&lowcost[j]<=min) min=lowcost[k=j];//最终找到的点的序号赋给k
}
printf("%d %d\n",k,closest[k] );//打印选择的边,和它的父亲结点
lowcost[k]=0;//标记k点为已经被选了
for(j=0;j<n;j++)
{
if(lowcost[j]&&g[k][j]<lowcost[j])//对于从k出发的所有边(k,j),更新lowcost[j]=min(lowcost[j],g[k][j]);
{
lowcost[j]=g[k][j];
closest[j]=k;//使得点j的父亲为k
}
}
}
}
Kruskal算法模板
贪婪思想
1.将边的权值从小到大进行排序
2.选择小的权值的边,如果是左右端点是连通的,则跳到下一条,否则把该条边选进来,使得左右端点连通
3.直到所有的点都是连通的
struct node
{
int u,v,w;
}e[A];//定义结构体e,来存放每条边的左端点u,右端点v,权值w
int f[MAX];
int find(int x)
{
return f[x]==x ? x : f[x]=find(f[x]);//寻找点x的根结点,同时进行路径压缩
}
void Union_set(int x,int y,int w)//判断根节点x,y是否相同,相同则它们是连通的,不进行处理,否则使它们连通
{
if(x!=y)
{
f[x]=y;
}
}
bool cmp(node x,node y)
{
return x.w<y.w;//将边的权值从小到大进行排序
}