#include <cstdio> #include <vector> #include <random> #include <cstdlib> #include <cassert> #define REP(i,n) for(int i=0; i<(n); ++i) #define FOR(i,p,k) for(int i=(p); i<=(k); ++i) typedef long long LL; enum { INF = 2000000000 }; template<typename T> inline void checkmin(T &a, T b){ if(a>b) a = b; } template<typename T> inline void checkmax(T &a, T b){ if(a<b) a = b; } std::mt19937 rnd(7263847); struct In { int n; std::vector<int> G; int & at(int i, int j){ return G[i*n+j]; } int operator()(int i, int j) const { return G[i*n+j]; } void read() { scanf("%d",&n); n++; G.resize(n*n); REP(i,n) at(i,i) = 0; REP(i,n-1) FOR(j,i+1,n-1) { scanf("%d",&at(i,j)); at(j,i) = at(i,j); } } void gen(int _n) { n = _n; int x = 1000000000; G.resize(n*n); REP(i,n) at(i,i) = 0; REP(i,n) REP(j,i) at(i,j) = at(j,i) = rnd()%x+1; } void print() { REP(i,n){ REP(j,n) printf("%d "); puts(""); } } }; LL go(const In &I) { int n = I.n; std::vector<int> D(n); REP(i,n) D[i] = I(0,i); LL res = 0; while(1) { int j=-1; REP(i,n) if(D[i] && (j==-1 || D[i]<D[j])) j = i; if(j==-1) break; res += D[j]; REP(i,n) checkmin(D[i],I(j,i)); } return res; } struct Brute { int n; std::vector<int> A; int & at(int i, int j){ return A[n*i+j]; } const In *I; LL rec(int i) { if(i<n) { LL res = LL(INF)*INF; REP(j0,n) FOR(j1,j0+1,n) { REP(j,n) at(i,j) = 0; FOR(j,j0,j1-1) at(i,j) = 1; checkmin(res,(*I)(j0,j1)+rec(i+1)); } return res; } REP(m,1<<n) if(m) { bool ok = 0; REP(j,n) { bool c = 0; REP(i,n) if(m>>i&1) c ^= at(i,j); if(c){ ok = 1; break; } } if(!ok) return LL(INF)*INF; } return 0; } LL run(const In &_I) { I = &_I; n = I->n-1; A.resize(n*n); return rec(0); } }; void test() { REP(_,100){ In I; I.gen(1000); assert(go(I)>=999); } puts("crash test complete"); for(int c=0;; c++) { In I; I.gen(6); Brute brute; LL b = brute.run(I); LL s = go(I); if(b!=s) { printf("ERROR (s=%lld; b=%lld)\n",s,b); I.print(); exit(1); } printf("ok (s=%lld; b=%lld)\n",s,b); } } int main() { //test(); In I; I.read(); printf("%lld\n",go(I)); 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 129 130 131 132 133 134 135 | #include <cstdio> #include <vector> #include <random> #include <cstdlib> #include <cassert> #define REP(i,n) for(int i=0; i<(n); ++i) #define FOR(i,p,k) for(int i=(p); i<=(k); ++i) typedef long long LL; enum { INF = 2000000000 }; template<typename T> inline void checkmin(T &a, T b){ if(a>b) a = b; } template<typename T> inline void checkmax(T &a, T b){ if(a<b) a = b; } std::mt19937 rnd(7263847); struct In { int n; std::vector<int> G; int & at(int i, int j){ return G[i*n+j]; } int operator()(int i, int j) const { return G[i*n+j]; } void read() { scanf("%d",&n); n++; G.resize(n*n); REP(i,n) at(i,i) = 0; REP(i,n-1) FOR(j,i+1,n-1) { scanf("%d",&at(i,j)); at(j,i) = at(i,j); } } void gen(int _n) { n = _n; int x = 1000000000; G.resize(n*n); REP(i,n) at(i,i) = 0; REP(i,n) REP(j,i) at(i,j) = at(j,i) = rnd()%x+1; } void print() { REP(i,n){ REP(j,n) printf("%d "); puts(""); } } }; LL go(const In &I) { int n = I.n; std::vector<int> D(n); REP(i,n) D[i] = I(0,i); LL res = 0; while(1) { int j=-1; REP(i,n) if(D[i] && (j==-1 || D[i]<D[j])) j = i; if(j==-1) break; res += D[j]; REP(i,n) checkmin(D[i],I(j,i)); } return res; } struct Brute { int n; std::vector<int> A; int & at(int i, int j){ return A[n*i+j]; } const In *I; LL rec(int i) { if(i<n) { LL res = LL(INF)*INF; REP(j0,n) FOR(j1,j0+1,n) { REP(j,n) at(i,j) = 0; FOR(j,j0,j1-1) at(i,j) = 1; checkmin(res,(*I)(j0,j1)+rec(i+1)); } return res; } REP(m,1<<n) if(m) { bool ok = 0; REP(j,n) { bool c = 0; REP(i,n) if(m>>i&1) c ^= at(i,j); if(c){ ok = 1; break; } } if(!ok) return LL(INF)*INF; } return 0; } LL run(const In &_I) { I = &_I; n = I->n-1; A.resize(n*n); return rec(0); } }; void test() { REP(_,100){ In I; I.gen(1000); assert(go(I)>=999); } puts("crash test complete"); for(int c=0;; c++) { In I; I.gen(6); Brute brute; LL b = brute.run(I); LL s = go(I); if(b!=s) { printf("ERROR (s=%lld; b=%lld)\n",s,b); I.print(); exit(1); } printf("ok (s=%lld; b=%lld)\n",s,b); } } int main() { //test(); In I; I.read(); printf("%lld\n",go(I)); return 0; } |