もちろん、鉱業の発展には最初に鉱山が必要です。リトルFFは前回の遠征で得た富の1000分の1を費やし、誰かに島を掘るように誘いました。
鉱山ですが、鉱山の電力供給を考えるのを忘れているようです。電気の供給を確保するために、リトルFFは2つの方法を考えました。
ヴィヴィを犠牲にして発電所を建設する
(発電所の出力電力は任意の数の鉱山に供給できます)。この鉱山を置くII
すでに電力を供給している別の鉱山で
電力網の確立の間のコストは、pi、jpi、j
。リトルFFは、すべての鉱山の電力供給を確保するための最小コストのソリューションを思い付くのを手伝ってくれることを望んでいます。入力フォーマットの最初の行には整数nnが含まれています
、地雷の総数を示します。次のnn
行、行ごとに1つの整数、ii
ビビ
セクションIIで表現
鉱山に発電所を建設するコスト。次はn×nn×n
マトリックスPP
、どこにpi、jpi、j
セクションIIで表現
鉱山とjj
鉱山間に電力網を確立するコスト。データ保証pi、j = pj、ipi、j = pj、i
,且 pi,i=0pi,i=0
。出力フォーマットは、すべての鉱山が十分なパワーを得るための最小コストを表す整数を出力します。データ範囲1≤n≤3001≤n≤300
、
0≤vi、pi、j≤1050≤vi、pi、j≤105
入力例:4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
出力例:9
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 310;
int dist[N];
int w[N][N];
bool st[N];
int n;
int prim(){
memset(dist, 0x3f, sizeof dist);
dist[0] = 0;
int res = 0;
for (int i = 0; i < n + 1; i ++){
int t = -1;
for (int j = 0; j <= n; j ++)
if (!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
st[t] = true;
res += dist[t];
for (int i = 0; i <= n; i ++) dist[i] = min(dist[i], w[t][i]);
}
return res;
}
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; i ++){
scanf("%d", &w[0][i]);
w[i][0] = w[0][i];
}
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
scanf("%d", &w[i][j]);
printf("%d\n", prim());
return 0;
}