#include<iostream>
#include<queue>
#include<stdio.h>
#define ll long long
using namespace std;
const int maxn = 111;
int a[maxn][maxn];
int dis[maxn];
int n, m, x, y;
void prim() {
int i, j, k, mina;
bool f[maxn];
for (i = 2;i <= n;++i) {
f[i] = 0;
dis[i] = a[1][i];
}
dis[1] = 0;
f[1] = 1;
for (i = 1;i <= n - 1;++i) {
mina = 9999999;
k = 0;
for (j = 1;j <= n;++j) {
if (!f[j] && dis[j] < mina) {
mina = dis[j];
k = j;
}
}
if (k == 0) return;
f[k] = 1;
for (j = 1;j <= n;++j) {
if (!f[j] && a[k][j] != 9999999 && dis[j] > a[k][j]) {
dis[j] = a[k][j];
}
}
}
}
int main() {
while (cin>>n) {
for (int i = 1;i <= n;++i)
for (int j = 1;j <= n;++j)
cin>>a[i][j];
cin>>m;
while (m--) {
cin>>x>>y;
a[x][y] = a[y][x] = 0;
}
prim();
int ans = 0;
for (int i = 1;i <= n;++i)
ans += dis[i];
cout<<ans<<endl;
}
}
最小生成树,就是一开始有一些联通了, 所以要在标记数组里面进行标记,然后再从没标记的里面继续挑选最短的修路+标记,直到所有都标记了就可以了,没什么坑难点