题目大意:
建造一个水库需要花费 (w_i),连接两块土地需要花费 (P_{i,j}),计算所有土地都有水时所需的最少代价。
正文:
在 (0) 处建立一个超级原点就可直接最小生成树。
代码:
int FIND(int x){return (x==fa[x])?x:fa[x]=FIND(fa[x]);}
void add(int u, int v, int w)
{
e[++tot] = (edge){u, v, head[u], w}, head[u] = tot;
}
int cmp (edge a, edge b)
{
return a.w < b.w;
}
int main()
{
scanf ("%d", &n);
for (int i = 0; i <= n; ++i) fa[i] = i;
for (int i = 1; i <= n; ++i)
{
int w;
scanf ("%d", &w);
add(0, i, w);
}
for (register int i = 1; i <= n; ++i)
{
for (register int j = 1; j <= n; ++j)
{
int w;
scanf ("%d", &w);
if (i == j)continue;
add(i, j, w);
}
}
sort(e + 1, e + 1 + tot, cmp);
for (int i = 1; i <= tot ; i++)
{
int f = FIND(e[i].from), t = FIND(e[i].to);
if (f == t) continue;
fa[f] = t;
ans += e[i].w * 1ll;
}
printf ("%lld", ans);
return 0;
}