蒜国有 n 座基站,现在蒜头君想给基站之间布设光纤,使得任意两座基站都是连通的,光纤传输具有传递性,即如果基站 A 和基站 B 之间有光纤,基站 B 和基站 C 之间有光纤,则基站 A 和基站 C 也是连通的,可以通过中间基站 B 来完成传输。
不同的基站之间布设光纤的费用是不同的,现在蒜头君知道了任意两座基站之间布设光纤的费用,求问如何布设,可以使得任意两座基站都是连通的,且总费用最小。
输入格式
第一行输入一个整数 n(2≤n≤100),表示蒜头基站总数。
接下来输入 n×n 的矩阵。第 i 行第 j 列的整数表示第 i 座基站和第 j 座基站之间布设光纤的费用 wij(0≤wij ≤10,000)。
输出格式
输出一个整数,表示布设光纤的最小总费用,且使任意两座基站都是连通的。
样例输入
4
0 1 5 1
1 0 6 3
5 6 0 2
1 3 2 0
样例输出
4
#include
#include
#include
#include
using namespace std;
int G[110][110];
int INF=0x3f3f3f3f;
int dad[200];
struct edge{
int u,v,w;
}e[8000];
bool cmp(edge a,edge b)
{
return a.wint getdad(int i)
{
if(dad[i]==i)return dad[i];
return dad[i]=getdad(dad[i]);
}
int main() {
int n;
for (int i = 1; i <= 105; i++)
dad[i] = i;
memset(G, INF, sizeof(G));
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int a;
cin >> a;
if (a != 0)
G[i][j] = a;
}
}
int eid = 1;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (G[i][j] < INF) {
e[eid].u = i;
e[eid].v = j;
e[eid].w = G[i][j];
eid++;
}
}
}
sort(e+1, e+eid, cmp);
int rest = n;
int ans = 0;
for (int i = 1; i < eid - 1 && rest > 1; i++) {
int x = e[i].u;
int y = e[i].v;
if (getdad(x) != getdad(y)) {
dad[getdad(x)] = getdad(y);
ans += e[i].w;
rest--;
}
}
cout << ans;
return 0;
}