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