题解 | #用kruskal算法解决#
还是畅通工程
https://www.nowcoder.com/practice/d6bd75dbb36e410995f8673a6a2e2229
//采用kruskal算法,所以边要按权值从小到大排列,可采用优先队列处理。已加入的结点不能再加,采用并查集处理 #include "stdio.h" #include "queue" #define N 1000 using namespace std; int father[N]; int height[N]; int n; struct Edge{ int x;//起点 int y;//终点 int weight;//权重 }; bool operator < (Edge lhs,Edge rhs){ if (lhs.weight > rhs.weight) return true; else return false; } void init(int n){//并查集的初始化 for (int i = 1; i <= n; ++i) { father[i] = i; height[i] = 1; } } int find(int x){//查找祖先根节点 if (x != father[x]){ father[x] = find(father[x]); } return father[x]; } void Union(int x,int y){//并查集的合并 x = father[x]; y = father[y]; if (height[x] > height[y]){ father[y] = x; } else if (height[x] < height[y]){ father[x] = y; } else{ father[x] = y; ++height[y]; } } int main(){ int x,y,weight; priority_queue<Edge> myPQueue; while (scanf("%d",&n)!=EOF){ if(n == 0) break; for (int i = 0; i < n*(n-1)/2; ++i) { Edge edge; scanf("%d%d%d",&x,&y,&weight); edge.x = x;edge.y = y;edge.weight = weight; myPQueue.push(edge); } init(n);int sum = 0; while (!myPQueue.empty()){ Edge edge = myPQueue.top(); myPQueue.pop(); //看edge(x,y)是否在同一个并查集中 //若不在同一个则Union(同时加上权值),否在同一个则continue if (find(edge.x) == find(edge.y)){//x与y在同一个并查集中 continue; } else{ Union(edge.x,edge.y); sum += edge.weight; } } printf("%d\n",sum); } }