#include <algorithm>#include <iostream>//// kruskal + 并查集 + 边表//struct node {
int from;
int to;
int w;
};
node edge[102 * 100];
int parent[102];
bool cmp(node a, node b) {
if (a.w <= b.w)
returntrue;
returnfalse;
}
//查找已经建完道路的顶点int find(int a) {
if (a != parent[a])
return find(parent[a]);
elsereturn a;
}
int kruskal(int n, int m) {
std::sort(edge, edge + m, cmp); //将边的权值从小到大排序int i, x, y, ans = 0;
for (i = 0; i < m; i++) {
x = edge[i].from;
y = edge[i].to;
x = find(x);
y = find(y);
if (x != y) {
ans += edge[i].w;
parent[y] = x;
}
}
return ans;
}
int main() {
int n, q, k, i, j, m;
while (std::cin >> n) {
m = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
std::cin >> k;
if (i >= j)
continue; //标记过的不用重复记录
edge[m].from = i;
edge[m].to = j;
edge[m].w = k;
m++;
}
}
for (k = 1; k <= n; k++)
parent[k] = k;
std::cin >> q;
//将建完的道路的起点和终点都置为相同的起点for (k = 1; k <= q; k++) {
std::cin >> i >> j;
i = find(i);
j = find(j);
parent[j] = i;
}
// n个点,m条边std::cout << kruskal(n, m) << std::endl;
}
return0;
}