直接用Prim最小生成树算法,注意权值要把两个端点的值加上,第一次WA了。。没有把d数组的初始值设的够大,才设了1024,受遗留代码的毒害啊。。改成9999就过了,因为最大权值也就1000+1000+1000
#include<stdio.h>
#include<string.h>
int main()
{
int t, a[500][500], k[500], d[500], p[500], v[500];
scanf("%d", &t);
while (t--)
{
int n, i, j, temp;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &v[i]);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
scanf("%d", &temp);
a[i][j] = i == j ? temp : temp + v[i] + v[j];
}
memset(k, 0, 500 * sizeof(int));
memset(p, -1, 500 * sizeof(int));
for (i = 0; i < 500; i++)
d[i] = 9999;
d[0] = 0;
int min, now = 0, next;
for (i = 0; i < n; i++)
{
k[now] = 1;
min = 99999;
for (j = 0; j < n; j++)
{
if (a[now][j] && !k[j] && a[now][j] < d[j])
{
d[j] = a[now][j];
p[j] = now;
}
if (!k[j] && d[j] < min)
{
min = d[j];
next = j;
}
}
now = next;
}
int sum = 0;
for (i = 0; i < n; i++)
if (p[i] != -1)
sum += a[i][p[i]];
printf("%d\n", sum);
}
return 0;
}