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;//将边的权值从小到大进行排序 }