#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; } |