#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <queue>
#include <stack>
#define NDEBUG
using namespace std;
int n;
vector< pair< int, pair<int,int> > > pairs;
bool dirty_check[2001][2001];
int next2[2001];
int prev2[2001];
const int NONE = 0;
bool is_checked(int a, int b)
{
int pos = a;
while(pos<=n)
{
if(next2[pos]==NONE)
return false;
if(next2[pos]==b)
return true;
pos = next2[pos]+1;
}
return false;
}
void check(int a, int b)
{
stack< pair<int,int>, vector<pair<int,int> > > s;
s.push(make_pair(a,b));
while(!s.empty())
{
a = s.top().first;
b = s.top().second;
s.pop();
assert(a<=b);
if(dirty_check[a][b])
continue;
dirty_check[a][b] = true;
if(next2[a]!=NONE )
{
if(next2[a]==b)
{
continue;
}
else if(next2[a]<b)
{
s.push(make_pair(next2[a]+1,b));
}
else if(next2[a]>b)
{
int c = next2[a];
prev2[c] = NONE;
next2[a] = NONE;
s.push(make_pair(b+1,c));
}
}
if(prev2[b]!=NONE )
{
if(prev2[b]==a)
continue;
else if(prev2[b]>a)
{
s.push(make_pair(a,prev2[b]-1));
}
else if(prev2[b]<a)
{
int c = prev2[b];
next2[c] = NONE;
prev2[b] = NONE;
s.push(make_pair(c,a-1));
}
}
if(prev2[b]==NONE && next2[a]==NONE)
{
prev2[b] = a;
next2[a] = b;
}
}
}
long long int solve()
{
long long int total_cost = 0;
sort(pairs.begin(),pairs.end());
assert(pairs.size()==n*(n+1)/2);
int inserted = 0;
for(unsigned int i=0; i<pairs.size(); ++i)
{
int cost = pairs[i].first;
int a = pairs[i].second.first;
int b = pairs[i].second.second;
if( is_checked(a,b) == false )
{
check(a,b);
total_cost += cost;
++inserted;
if(inserted>=n)
break;
}
}
return total_cost;
}
void read(int n)
{
for(int i=1;i<=n;++i)
for(int j=i;j<=n;++j)
{
int cost;
cin >> cost;
pairs.push_back(make_pair(cost,make_pair(i,j)));
}
}
int main()
{
cin.sync_with_stdio(0);
cin >> n;
read(n);
cout << solve();
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #include <iostream> #include <vector> #include <algorithm> #include <cassert> #include <queue> #include <stack> #define NDEBUG using namespace std; int n; vector< pair< int, pair<int,int> > > pairs; bool dirty_check[2001][2001]; int next2[2001]; int prev2[2001]; const int NONE = 0; bool is_checked(int a, int b) { int pos = a; while(pos<=n) { if(next2[pos]==NONE) return false; if(next2[pos]==b) return true; pos = next2[pos]+1; } return false; } void check(int a, int b) { stack< pair<int,int>, vector<pair<int,int> > > s; s.push(make_pair(a,b)); while(!s.empty()) { a = s.top().first; b = s.top().second; s.pop(); assert(a<=b); if(dirty_check[a][b]) continue; dirty_check[a][b] = true; if(next2[a]!=NONE ) { if(next2[a]==b) { continue; } else if(next2[a]<b) { s.push(make_pair(next2[a]+1,b)); } else if(next2[a]>b) { int c = next2[a]; prev2[c] = NONE; next2[a] = NONE; s.push(make_pair(b+1,c)); } } if(prev2[b]!=NONE ) { if(prev2[b]==a) continue; else if(prev2[b]>a) { s.push(make_pair(a,prev2[b]-1)); } else if(prev2[b]<a) { int c = prev2[b]; next2[c] = NONE; prev2[b] = NONE; s.push(make_pair(c,a-1)); } } if(prev2[b]==NONE && next2[a]==NONE) { prev2[b] = a; next2[a] = b; } } } long long int solve() { long long int total_cost = 0; sort(pairs.begin(),pairs.end()); assert(pairs.size()==n*(n+1)/2); int inserted = 0; for(unsigned int i=0; i<pairs.size(); ++i) { int cost = pairs[i].first; int a = pairs[i].second.first; int b = pairs[i].second.second; if( is_checked(a,b) == false ) { check(a,b); total_cost += cost; ++inserted; if(inserted>=n) break; } } return total_cost; } void read(int n) { for(int i=1;i<=n;++i) for(int j=i;j<=n;++j) { int cost; cin >> cost; pairs.push_back(make_pair(cost,make_pair(i,j))); } } int main() { cin.sync_with_stdio(0); cin >> n; read(n); cout << solve(); return 0; } |
English