读懂题意,就都是是水题
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <algorithm>
#define N 1001
const int maxn=(N*N-N) / 2 + 1;
using namespace std;
struct edge
{
int x, y, value;
}edge[maxn];
int n, len, fa[N];
bool cmp(struct edge a, struct edge b)
{
return a.value < b.value;
}
void input()
{
int price[N], i, j, temp;
int k=1;
scanf("%d", &n);
len = (n*n - n) / 2;
for(i=1; i<=n; i++)
scanf("%d", &price[i]);
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
scanf("%d", &temp);
if(i<j)
{
edge[k].x = i;
edge[k].y = j;
edge[k].value = price[i] + price[j] + temp;
k++;
}
}
}
int find(int x)
{
/* while(x != fa[x])
x = fa[x];
return x;*/
return x==fa[x]?x:find(fa[x]);
}
void KRUSKAL()
{
int ans=0;
for(int i=1; i<=n; i++)
fa[i] = i;
sort(edge+1, edge+len+1, cmp);
for(int i=1; i<=len; i++)
{
int x1 = find( edge[i].x );
int x2 = find( edge[i].y );
if(x1 != x2)
{
fa[x1] = x2;
ans += edge[i].value;
}
}
printf("%d\n", ans);
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
input();
KRUSKAL();
}
return 0;
}