#include <cstdio>
#include <algorithm>
#define X first
#define Y second
using namespace std;
const int MAXN = 2003, INF = 1000000009;
int t[MAXN][MAXN];
bool zuzyte[MAXN];
int ost[MAXN];
pair<int, int> drzewo[2 << 12];
int n, M = 1;
int result;
void dodaj(int val, int poz)
{
int va = M + poz;
drzewo[va] = make_pair(val, poz);
while(va > 1)
{
va /= 2;
if(drzewo[2 * va].X < drzewo[2 * va + 1].X)
{
drzewo[va] = drzewo[2 * va];
} else drzewo[va] = drzewo[2 * va + 1];
}
}
void fillTab()
{
for(int i = 0; i <= n; i++)
for(int j = 0; j <= n; j++)
t[i][j] = INF;
for(int i = 0; i < 2*M + 1; i++)
drzewo[i].X = INF;
}
void read()
{
scanf("%d", &n);
while(M < n) M *= 2;
fillTab();
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++)
scanf("%d", &t[i][j]);
}
for(int i = 0; i < n; i++)
{
dodaj(t[i][i], i);
ost[i] = i;
}
}
void przesun(pair<int, int> data)
{
int poz = ost[data.Y];
while(zuzyte[poz] == 1 && poz < n) poz++;
if(poz == n - 1) data.X = INF;
else data.X = t[data.Y][poz];
zuzyte[poz] = 1;
ost[data.Y] = poz;
dodaj(data.X, data.Y);
}
int minZPrzedz(int ktory)
{
int mini = INF;
for(int i = ktory; i < n; i++)
for(int j = 0; j < n; j++)
mini = min(mini, t[i][j]);
return mini;
}
int main()
{
read();
for(int i = 1; i < n; i++)
{
result += drzewo[1].first;
przesun(drzewo[1]);
/*printf("Nowy wynik: %d\n", result);
printf("dzefko:\n");
for(int i = 1; i <= 2 * M; i++)
{
printf("%d ", drzewo[i].X);
if(i == 1 || i == 5 || i == 9 || i == 17) printf("\n");
}*/
}
for(int i = 0; i < n; i++)
{
if(zuzyte[i] == 0)
{
result += minZPrzedz(i);
break;
}
}
printf("%d", result);
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include <cstdio> #include <algorithm> #define X first #define Y second using namespace std; const int MAXN = 2003, INF = 1000000009; int t[MAXN][MAXN]; bool zuzyte[MAXN]; int ost[MAXN]; pair<int, int> drzewo[2 << 12]; int n, M = 1; int result; void dodaj(int val, int poz) { int va = M + poz; drzewo[va] = make_pair(val, poz); while(va > 1) { va /= 2; if(drzewo[2 * va].X < drzewo[2 * va + 1].X) { drzewo[va] = drzewo[2 * va]; } else drzewo[va] = drzewo[2 * va + 1]; } } void fillTab() { for(int i = 0; i <= n; i++) for(int j = 0; j <= n; j++) t[i][j] = INF; for(int i = 0; i < 2*M + 1; i++) drzewo[i].X = INF; } void read() { scanf("%d", &n); while(M < n) M *= 2; fillTab(); for(int i = 0; i < n; i++) { for(int j = i; j < n; j++) scanf("%d", &t[i][j]); } for(int i = 0; i < n; i++) { dodaj(t[i][i], i); ost[i] = i; } } void przesun(pair<int, int> data) { int poz = ost[data.Y]; while(zuzyte[poz] == 1 && poz < n) poz++; if(poz == n - 1) data.X = INF; else data.X = t[data.Y][poz]; zuzyte[poz] = 1; ost[data.Y] = poz; dodaj(data.X, data.Y); } int minZPrzedz(int ktory) { int mini = INF; for(int i = ktory; i < n; i++) for(int j = 0; j < n; j++) mini = min(mini, t[i][j]); return mini; } int main() { read(); for(int i = 1; i < n; i++) { result += drzewo[1].first; przesun(drzewo[1]); /*printf("Nowy wynik: %d\n", result); printf("dzefko:\n"); for(int i = 1; i <= 2 * M; i++) { printf("%d ", drzewo[i].X); if(i == 1 || i == 5 || i == 9 || i == 17) printf("\n"); }*/ } for(int i = 0; i < n; i++) { if(zuzyte[i] == 0) { result += minZPrzedz(i); break; } } printf("%d", result); return 0; } |
English