#include <cstdio>
#include <algorithm>
#include <cstdlib>
#define scanf(args...) (scanf(args) ? : 0)
const int MAXN = 2005;
const int INF = 1e9;
int T[MAXN][MAXN];
int shortestBegin[MAXN];
int shortestEnd[MAXN];
std::pair<int, int> p[MAXN*MAXN];
bool known[MAXN][MAXN];
int rep[MAXN];
int n;
int find(int u) {
if (rep[u] == u)
return u;
return rep[u] = find(rep[u]);
}
void merge(int u, int v) {
if (u == -1 || u == INF)
return;
if (v == -1 || v == INF)
return;
//printf("lacze %d %d\n", u, v);
rep[find(u)] = find(v);
}
void add(int a, int b) {
if (known[a][b])
return;
known[a][b] = true;
if (shortestBegin[a] != INF) {
if (shortestBegin[a] < b)
add(shortestBegin[a]+1, b);
else
add(b+1, shortestBegin[a]);
}
if (shortestEnd[b] != -1) {
if (shortestEnd[b] < a)
add(shortestEnd[b], a-1);
else
add(a, shortestEnd[b]-1);
}
shortestBegin[a] = std::min(shortestBegin[a], b);
shortestEnd[b] = std::max(shortestEnd[b], a);
//printf("enabling %d %d\n", a, b);
//merge(a, b);
/*if (b+1 < n && shortestBegin[b+1] != INF)
merge(a+1, shortestBegin[b+1]);
if (a-1 >= 0 && shortestEnd[a-1] != -1)
merge(b-1, shortestEnd[a-1]);*/
}
bool cmp(std::pair<int, int> p1, std::pair<int, int> p2) {
return T[p1.first][p1.second] < T[p2.first][p2.second];
}
bool enabled(int a, int b) {
/*if (a == b)
return shortestBegin[a] == a;
return find(a) == find(b);*/
int pos = a;
while (shortestBegin[pos] < b)
pos = shortestBegin[pos]+1;
return shortestBegin[pos] == b;
}
int main() {
std::fill(shortestBegin, shortestBegin+MAXN, INF);
std::fill(shortestEnd, shortestEnd+MAXN, -1);
scanf("%d", &n);
for (int i=0; i<n; i++)
rep[i] = i;
int size = 0;
for (int i=0; i<n; i++)
for (int j=i; j<n; j++) {
scanf("%d", &T[i][j]);
p[size++] = { i, j };
}
std::sort(p, p+size, cmp);
long long res = 0;
for (int i=0; i<size; i++) {
int a = p[i].first, b = p[i].second;
if (!enabled(a, b)) {
//printf("=>>dodaje %d %d %d\n", a, b, T[a][b]);
res += T[a][b];
add(a, b);
}
//else
// printf("==>olewam %d %d\n", a, b);
}
printf("%Ld\n", res);
}
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 105 106 | #include <cstdio> #include <algorithm> #include <cstdlib> #define scanf(args...) (scanf(args) ? : 0) const int MAXN = 2005; const int INF = 1e9; int T[MAXN][MAXN]; int shortestBegin[MAXN]; int shortestEnd[MAXN]; std::pair<int, int> p[MAXN*MAXN]; bool known[MAXN][MAXN]; int rep[MAXN]; int n; int find(int u) { if (rep[u] == u) return u; return rep[u] = find(rep[u]); } void merge(int u, int v) { if (u == -1 || u == INF) return; if (v == -1 || v == INF) return; //printf("lacze %d %d\n", u, v); rep[find(u)] = find(v); } void add(int a, int b) { if (known[a][b]) return; known[a][b] = true; if (shortestBegin[a] != INF) { if (shortestBegin[a] < b) add(shortestBegin[a]+1, b); else add(b+1, shortestBegin[a]); } if (shortestEnd[b] != -1) { if (shortestEnd[b] < a) add(shortestEnd[b], a-1); else add(a, shortestEnd[b]-1); } shortestBegin[a] = std::min(shortestBegin[a], b); shortestEnd[b] = std::max(shortestEnd[b], a); //printf("enabling %d %d\n", a, b); //merge(a, b); /*if (b+1 < n && shortestBegin[b+1] != INF) merge(a+1, shortestBegin[b+1]); if (a-1 >= 0 && shortestEnd[a-1] != -1) merge(b-1, shortestEnd[a-1]);*/ } bool cmp(std::pair<int, int> p1, std::pair<int, int> p2) { return T[p1.first][p1.second] < T[p2.first][p2.second]; } bool enabled(int a, int b) { /*if (a == b) return shortestBegin[a] == a; return find(a) == find(b);*/ int pos = a; while (shortestBegin[pos] < b) pos = shortestBegin[pos]+1; return shortestBegin[pos] == b; } int main() { std::fill(shortestBegin, shortestBegin+MAXN, INF); std::fill(shortestEnd, shortestEnd+MAXN, -1); scanf("%d", &n); for (int i=0; i<n; i++) rep[i] = i; int size = 0; for (int i=0; i<n; i++) for (int j=i; j<n; j++) { scanf("%d", &T[i][j]); p[size++] = { i, j }; } std::sort(p, p+size, cmp); long long res = 0; for (int i=0; i<size; i++) { int a = p[i].first, b = p[i].second; if (!enabled(a, b)) { //printf("=>>dodaje %d %d %d\n", a, b, T[a][b]); res += T[a][b]; add(a, b); } //else // printf("==>olewam %d %d\n", a, b); } printf("%Ld\n", res); } |
English