#include <iostream> #include <vector> #include <algorithm> #include <utility> using namespace std; class polaczenie {public: int i,j; int koszt; bool operator < (const polaczenie& other ) const {return koszt<other.koszt;} polaczenie (int ii,int jj,int k):i(ii),j(jj),koszt(k){} }; int main() { int n; cin.sync_with_stdio(false); cin>>n; /* generator zośliwego przypadku cout<<n<<endl; for (int i=1;i<=n;i++) { //if (i<n) cout<<"1 "; for(int j=i;j<=n-1;j++) { cout<<j-i<<" "; } cout<<2*n<<" "<<endl; } return 0;*/ vector <polaczenie> polaczenia; polaczenia.reserve((n+2)*(n+2)/2); for (int i=1;i<=n;i++) for(int j=i;j<=n;j++) { int c; cin>>c; // C[i][j]=c; polaczenia.emplace_back(i,j,c); } sort(polaczenia.begin(),polaczenia.end()); vector<int> konce(n+1,0); // koniec[i]=j oznacza belkę i-j. int wymiar=0; int index=0; int64_t koszt=0; while (wymiar<n) { polaczenie belka = polaczenia[index]; index++; while ( konce[belka.i]!=0 ) { if (konce[belka.i]==belka.j) { // cout<<"jest"<<endl; belka.i=0; break; } int M,m; if (konce[belka.i]>belka.j) { M=konce[belka.i]; m=belka.j; }else { m=konce[belka.i]; M=belka.j; } //heurystyka walczaca z O(n^3) //chcemy, aby belka bazowa zajmowałą z grubsza //polowę miejsca miedzy swoim początkiem a końcem. if ( abs(M-(belka.i+n/2))<abs(m-(belka.i+n/2) ) ) konce[belka.i]=M; else konce[belka.i]=m; //nie wiemy jeszcze, czy belka wejdzie do bazy, ale //jeśli nie wejdzie, tzn była liniiowo zależna od bazy // - mamy prawo ją odjąć. belka.i=m+1; belka.j = M; } if (belka.i!=0) { konce[belka.i]=belka.j; wymiar++; koszt+=belka.koszt; } } cout<<koszt<<endl; 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 | #include <iostream> #include <vector> #include <algorithm> #include <utility> using namespace std; class polaczenie {public: int i,j; int koszt; bool operator < (const polaczenie& other ) const {return koszt<other.koszt;} polaczenie (int ii,int jj,int k):i(ii),j(jj),koszt(k){} }; int main() { int n; cin.sync_with_stdio(false); cin>>n; /* generator zośliwego przypadku cout<<n<<endl; for (int i=1;i<=n;i++) { //if (i<n) cout<<"1 "; for(int j=i;j<=n-1;j++) { cout<<j-i<<" "; } cout<<2*n<<" "<<endl; } return 0;*/ vector <polaczenie> polaczenia; polaczenia.reserve((n+2)*(n+2)/2); for (int i=1;i<=n;i++) for(int j=i;j<=n;j++) { int c; cin>>c; // C[i][j]=c; polaczenia.emplace_back(i,j,c); } sort(polaczenia.begin(),polaczenia.end()); vector<int> konce(n+1,0); // koniec[i]=j oznacza belkę i-j. int wymiar=0; int index=0; int64_t koszt=0; while (wymiar<n) { polaczenie belka = polaczenia[index]; index++; while ( konce[belka.i]!=0 ) { if (konce[belka.i]==belka.j) { // cout<<"jest"<<endl; belka.i=0; break; } int M,m; if (konce[belka.i]>belka.j) { M=konce[belka.i]; m=belka.j; }else { m=konce[belka.i]; M=belka.j; } //heurystyka walczaca z O(n^3) //chcemy, aby belka bazowa zajmowałą z grubsza //polowę miejsca miedzy swoim początkiem a końcem. if ( abs(M-(belka.i+n/2))<abs(m-(belka.i+n/2) ) ) konce[belka.i]=M; else konce[belka.i]=m; //nie wiemy jeszcze, czy belka wejdzie do bazy, ale //jeśli nie wejdzie, tzn była liniiowo zależna od bazy // - mamy prawo ją odjąć. belka.i=m+1; belka.j = M; } if (belka.i!=0) { konce[belka.i]=belka.j; wymiar++; koszt+=belka.koszt; } } cout<<koszt<<endl; return 0; } |