描述
该题的目的是要你统计图的连通分支数。
输入描述:
每个输入文件包含若干行,每行两个整数i,j,表示节点i和j之间存在一条边。
(请使用循环输入,可以参考该网址:https://www.nowcoder.com/discuss/276)
输出描述:
输出每个图的联通分支数。
输入
1 4
4 3
5 5
输出
2
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
int father[1010];
// i 数组下标是集合数据编号 father[i] 集合数据的父亲的编号
// 根i father[i] 和 i 相同
void InitDisjointSet(int n) {
// 0~n-1
for (int i = 0; i < n; ++i) {
father[i] = i;
}
}
int FindDisjointSet(int u) {
if (u == father[u]) {
return u;
}
else {
father[u] = FindDisjointSet(father[u]);
return father[u];
}
}
void UnionDisjointSet(int u, int v) {
int uroot = FindDisjointSet(u);
int vroot = FindDisjointSet(v);
father[vroot] = uroot;
}
struct Edge {
int u;
int v;
int weight;
// 构造函数的特点 类里面 没有返回值 名字和类名相同
Edge(int _u, int _v, int _weight) {
u = _u;
v = _v;
weight = _weight;
}
};
bool compare(Edge lhs, Edge rhs) {
return lhs.weight < rhs.weight;
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
if (n == 0) {
break;
}
vector<Edge> edgeVec;
InitDisjointSet(n + 1);
for (int i = 0; i < (n - 1) * n / 2; ++i) {
int u, v, weight;
scanf("%d%d%d", &u, &v, &weight);
//Edge e; 可以用类的构造函数简化
//e.u = u;
//e.v = v;
//e.weight = weight;
Edge e(u, v, weight);
edgeVec.push_back(e);
}
// kruskal
// 排序
sort(edgeVec.begin(), edgeVec.end(), compare);
// 遍历edgeVec 加入子图
int totalWeight = 0;
int curEdgeNum = 0;
for (int i = 0; i < edgeVec.size(); ++i) {
int u = edgeVec[i].u;
int v = edgeVec[i].v;
int weight = edgeVec[i].weight;
if (FindDisjointSet(u) != FindDisjointSet(v)) {
UnionDisjointSet(u, v);
++curEdgeNum;
totalWeight += weight;
if (curEdgeNum == n - 1) {
break;
}
}
}
printf("%d\n", totalWeight);
}
return 0;
}