int G[MAXN][MAXN];//权值矩阵 int vis[MAXN];//记录访问 int lowc[MAXN];//记录与树连接的边的权重 memset(G,INF,sizeof(G)); memset(vis,false,sizeof(vis)); memset(lowc,INF,sizeof(lowc));
//标号0-n-1,返回最小生成树的权值,返回-1表示不连通 int Prim(int n){ int ans = 0; //从0节点开始 vis[0] = true; //首先更新与0结点直接相连的边的权值。 for(int i = 1; i < n; i++) lowc[i] = G[0][i]; //循环n-1次 for(int i = 1; i < n; i++){ int minc = INF; int p = -1; //找到与当前树相连并且权值最小的边。 for(int j = 0; j < n; j++){ if(!vis[j]&&minc > lowc[j]){ minc = lowc[j]; p = j; } } //不连通 if(minc == INF) return -1; //更新树的权值 ans += minc; vis[p] = true; //继续更新新树的最小权值数组。 for(int j = 0; j < n; j++){ if(!vis[j]&&lowc[j] > G[p][j]) lowc[j] = G[p][j]; } } return ans; }
//传入点数,返回最小生成树的权值,如果不连通返回-1 int Kruskal(int n){ memset(F,-1,sizeof(F)); //先对边排序 sort(edge,edge+tol,cmp); int cnt = 0; //计算加入的边数。 int ans = 0; //最多循环tol次 for(int i = 0; i < tol; i++){ int u = edge[i].u; int v = edge[i].v; int w = edge[i].w; int t1 = find(u); int t2 = find(v); //如果属于不同集合,合并 if(t1 != t2){ ans+= w; F[t1] = t2; cnt++; } //共需合并n-1次,已经完成,可提前结束 if(cnt == n-1) break; } if(cnt < n-1) return -1;//不连通 return ans; }