void prim(Mgraph g,int v0,int &sum)//Mgraph 是连接矩阵,v是从哪个点开始,sum保存最小生成树的值。 { int lowcost[maxSize],vest[maxSize],v;//lowcost数组保存最小花费,vest保存是否用过 1是用过m,0是未到达 sum=0; v=v0; for(int i=0;i<g.n;i++) { lowcost[i]=g.edge[v][i]; vest[i]=0; } vest[v]=1; for(int i=0;i<g.n-1;i++)//已经一个点了,还需要n-1个点 { int min=Inf; int k=-1;//加进去哪个点。 for(int j=0;j<=g.n-1;j++) { if(vest[j]==0&&min>lowcost[j]) { k=j; min=lowcost[j]; } } sum=sum+min; vest[k]=1; for(int j=0;j<=g.n-1;j++) { if(vest[j]==0&&lowcost[j]>g.edge[j][k]) lowcost[j]=g.edge[j][k]; } } }
最小生成树
就是使n个点连通的所有边的权值最小的一个解
prim就是每次加进去一个点就更新路径。然后每次都加进去最短的路。
kruskal 就是我先不管 每次找这张图的最短边。如果这2条边已经联通了,就不加入,怎么判断联通呢——并查集
不会的可以看一下这个:https://blog.51cto.com/ahalei/2348145 看不会————立即推放弃考研。
开个玩笑,那就来一个有趣点的 https://blog.csdn.net/tingtingyuan/article/details/81697698
typedef struct Road { int a,b; int w; }Road; Road road[maxSize]; int father[maxSize]; int find_father(int n) { while (n!=father[n]) { n=father[n]; } return n; } void kruskal(Mgargh g,int &sum ,Road road[]) { sum=0; int N=g.n; int E=g.e; sort(road,road+E); for(int i=0;i<N;i++) father[i]=i;//并查集的初始化; for(int i=0;i<E;i++) { int a=find_father(road[i].a); int b=find_father(road[i].b); if(a!=b)//相等就是在同一个集合里面了。在加进去就变成环了。所以是不等于 { father[a]=b; sum=sum+road[i].w; } } }
这样写就是跑完所有边。我们可以记数,跑n-1条边,生成树n个点需要n-1个点