如图就是Kuskal算法 将图中的每条边按照权值从小到大排序,每次加起来就行,注意的是不要形成回路; 重点是如何用代码实现不能形成回路 看代码; #include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#define MaxSize 100using namespace std;int tu[MaxSize][MaxSize];struct Edge//储存边的两个顶点以及边的权值{ int begin1; int end1; int weight;};bool comp(Edge a,Edge b){ return a.weight<b.weight;}void Kruskal(int n){ int vest[MaxSize]; Edge E[MaxSize]; int k=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(tu[i][j]!=0) { E[k].begin1=i;//将这条边的一个顶点储存 E[k].end1=j;//将这条边的另一个顶点储存 E[k].weight=tu[i][j];//将边的权值储存 k++;//边的个数 } sort(E,E+k,comp);//按照边的权值从大到小排序 for(int i=0;i<=n;i++) vest[i]=i;//重点:将每个顶点初始化,看作是各不相同的集合 k=1; int j=1,u1,v1,sn1,sn2; int sum=0; while(k<n) { u1=E[j].begin1; v1=E[j].end1; sn1=vest[u1]; sn2=vest[v1];//此条边的两个点 if( sn1!=sn2)//两个点不属于一个集合 { k++; sum+=E[j].weight; printf("< %d , %d >: %d sum=%d\n", u1-1,v1-1,E[j].weight,sum); for(int i=1;i<=n;i++) if(vest[i]==sn2) vest[i]=sn1;//将找过的边的顶点都赋予相同的值,代表在一个集合内,此段代码将所有连在一起的顶点都标志成一个相同的值即 vest[顶点编号]都是相同的; } j++;//遍历下一条边 }}int main(){ int n; scanf("%d",&n);for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&tu[i][j]); Kruskal(n); return 0;}/*60 6 1 5 9999 99996 0 5 9999 3 99991 5 0 5 6 45 9999 5 0 9999 29999 3 6 9999 0 69999 9999 4 2 6 0 */