#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#define MAXN 500005
#define INF 1000000007
using namespace std;
struct EDGE
{
int u, v, w;
EDGE(){}
EDGE(int _u, int _v, int _w){u = _u; v = _v; w = _w;}
bool operator<(const EDGE &cmp)const
{
return w < cmp.w;
}
}edge[MAXN];
int n, fa[MAXN];
int val[MAXN];
int find(int x)
{
if(fa[x] == x) return x;
int t = find(fa[x]);
fa[x] = t;
return t;
}
int main()
{
int x;
scanf("%d", &n);
for(int i = 1; i <= n; i++) fa[i] = i;
for(int i = 1; i <= n; i++)
scanf("%d", &val[i]);//新建一个节点保存每个点建水库的费用
int cnt = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
scanf("%d", &x);
edge[cnt++] = EDGE(i, j, x);
}
for(int i = 1; i <= n; i++)
edge[cnt++] = EDGE(i, n + 1, val[i]);
sort(edge, edge + cnt);
int ans = 0;
for(int i = 0; i < cnt; i++)//kruscal算法最小生成树
{
int fx = find(edge[i].u);
int fy = find(edge[i].v);
if(fx != fy)
{
fa[fx] = fy;
ans += edge[i].w;
}
}
printf("%d\n", ans);
return 0;
}
08-09
08-09
08-09
08-09