Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.01 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #pragma comment(linker, "/stack:16777216")
  3. #include <string>
  4. #include <vector>
  5. #include <map>
  6. #include <list>
  7. #include <iterator>
  8. #include <set>
  9. #include <queue>
  10. #include <iostream>
  11. #include <sstream>
  12. #include <stack>
  13. #include <deque>
  14. #include <cmath>
  15. #include <memory.h>
  16. #include <cstdlib>
  17. #include <cstdio>
  18. #include <cctype>
  19. #include <algorithm>
  20. #include <utility>
  21. #include <time.h>
  22. using namespace std;
  23.  
  24. #define FOR(i, a, b) for(int i = (a); i < (b); ++i)
  25. #define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
  26. #define FILL(A,value) memset(A,value,sizeof(A))
  27.  
  28. #define ALL(V) V.begin(), V.end()
  29. #define SZ(V) (int)V.size()
  30. #define PB push_back
  31. #define MP make_pair
  32. #define Pi 3.14159265358979
  33.  
  34. typedef long long LL;
  35. typedef vector <int> VI;
  36. typedef pair <int, int> PII;
  37. using namespace std;
  38.  
  39.  
  40. const int MAX = 444;
  41.  
  42. int n;
  43. int D[MAX][MAX];
  44.  
  45. int NXT[MAX], PR[MAX];
  46. int COL[MAX];
  47.  
  48. vector<int> solve1()
  49. {
  50. FOR(i, 0, n)
  51. {
  52. NXT[i] = -1;
  53. PR[i] = -1;
  54. COL[i] = i;
  55. }
  56.  
  57. FOR(it, 0, n)
  58. {
  59. int s = -1, t = -1;
  60. int dmin = 1e+9;
  61. FOR(i, 0, n)
  62. if (NXT[i] == -1)
  63. {
  64. FOR(j, 0, n)
  65. if (PR[j] == -1 && (COL[i] != COL[j] || it == n - 1))
  66. {
  67. if (D[i][j] < dmin)
  68. {
  69. dmin = D[i][j];
  70. s = i;
  71. t = j;
  72. }
  73. }
  74. }
  75.  
  76. NXT[s] = t;
  77. PR[t] = s;
  78. int c = COL[t];
  79. FOR(i, 0, n)
  80. {
  81. if (COL[i] == c)
  82. COL[i] = COL[s];
  83. }
  84. }
  85.  
  86. int v = 0;
  87.  
  88. vector<int> res;
  89.  
  90. FOR(i, 0, n + 1)
  91. {
  92. res.push_back(v);
  93. v = NXT[v];
  94. }
  95.  
  96. return res;
  97. }
  98.  
  99. const int MAXDP = 20;
  100. int DP[MAXDP][1 << MAXDP];
  101.  
  102. LL getDp(int v, int mask) {
  103. if (DP[v][mask] != -1)return DP[v][mask];
  104. int val = 1e+9;
  105. int p = -1;
  106. FOR(i, 0, n)
  107. {
  108. if (i == v)continue;
  109. if (!(mask&(1 << v)))continue;
  110. int cur = getDp(i, mask ^ (1 << v)) + D[i][v];
  111. if (cur < val) {
  112. val = cur;
  113. p = i;
  114. }
  115. }
  116.  
  117. DP[v][mask] = val;
  118. return val;
  119. }
  120.  
  121. vector<int> solveDP()
  122. {
  123. FILL(DP, -1);
  124. DP[0][0] = 0;
  125. getDp(0, (1 << n) - 1);
  126. //cerr << "done" << endl;
  127. vector<int> res;
  128. int v = 0;
  129. int msk = (1 << n) - 1;
  130.  
  131. while (msk)
  132. {
  133. res.PB(v);
  134. int to = -1;
  135. FOR(i,0,n)
  136. if(i!=v)
  137. if(msk&(1<<i))
  138. if (DP[i][msk ^ (1 << v)] + D[i][v] == DP[v][msk]) {
  139. to = i;
  140. }
  141. msk ^= 1 << v;
  142. v = to;
  143. }
  144. res.PB(0);
  145.  
  146. return res;
  147. }
  148.  
  149. struct BranchSolver {
  150. bool us[MAX];
  151. VI bstPath;
  152. VI path;
  153. LL cost;
  154. LL LB;
  155. vector<PII> E[MAX];
  156. void init(LL lb)
  157. {
  158. LB = lb;
  159. FILL(us, 0);
  160. FOR(i, 0, n)
  161. {
  162. FOR(j, 0, n)if (i != j)E[i].PB(MP(D[i][j], j));
  163. sort(ALL(E[i]));
  164. }
  165. }
  166.  
  167. PII getMin(int v) {
  168. FOR(i, 0, SZ(E[v]))
  169. if (!(us[E[v][i].second] /*&&rand()%7==0*/))return E[v][i];
  170. return MP(0,-1);
  171. }
  172.  
  173. LL getEstim()
  174. {
  175. /* LL res = 0;
  176. FOR(i,0,n)
  177. if (!us[i]) {
  178. PII w = getMin(i);
  179. res += w.first;
  180. }*/
  181. LL avgEdge = LB / (n) * (n - path.size());
  182. return avgEdge;
  183. }
  184. bool END = false;
  185. void go(int v)
  186. {
  187. if (END || (path.size()&8) && (clock() / (double)CLOCKS_PER_SEC) > 0.21) {
  188. END = true; return;
  189. // cerr << "end"; exit(0);
  190. }
  191. if (path.size() == n) {
  192. if (cost+D[v][0] < LB) {
  193. LB = cost+D[v][0];
  194. bstPath = path;
  195. }
  196. return;
  197. }
  198. if (cost + getEstim() >= LB) return;
  199.  
  200. FOR(ind, 0, n-1) {
  201. int i = E[v][ind].second;
  202. if (us[i])continue;
  203. us[i] = 1;
  204. path.push_back(i);
  205. cost += D[v][i];
  206. go(i);
  207. cost -= D[v][i];
  208. us[i] = 0;
  209. path.pop_back();
  210. if ((v&47))break;
  211. }
  212. }
  213.  
  214. VI solve() {
  215. us[0] = 1;
  216. END = 0;
  217. cost = 0;
  218. path.PB(0);
  219. go(0);
  220. bstPath.PB(0);
  221. return bstPath;
  222. }
  223.  
  224. } BRANCH;
  225.  
  226.  
  227. LL getScore(vector<int> &v)
  228. {
  229. LL res = 0;
  230. FOR(i, 1, SZ(v))
  231. res += D[v[i - 1]][v[i]];
  232.  
  233. return res;
  234. }
  235.  
  236. void optimize(vector<int>& v)
  237. {
  238. LL score = getScore(v);
  239. FOR(i, 2, v.size() - 1)
  240. {
  241. int before = D[v[i-2]][v[i-1]] + D[v[i]][v[i+1]];
  242. int after = D[v[i-2]][v[i]] + D[v[i-1]][v[i+1]];
  243.  
  244. if (after < before)
  245. {
  246. swap(v[i], v[i-1]);
  247. }
  248. // swap(v[i], v[i - 1]);
  249. // LL cur = getScore(v);
  250. // if (cur > score)
  251. // {
  252. // swap(v[i], v[i - 1]);
  253. // }
  254. // score = min(score, cur);
  255. }
  256. }
  257.  
  258. void optimize2(VI& v)
  259. {
  260. int x = rand() % (SZ(v) - 1);
  261. int y = rand() % (SZ(v) - 1);
  262.  
  263. if (x == y) return;
  264. if (x > y) swap(x, y);
  265.  
  266. int before = D[v[x]][v[x+1]] + D[v[y]][v[y+1]];
  267. int after = D[v[x]][v[y]] + D[v[x+1]][v[y+1]];
  268. if (after < before)
  269. {
  270. reverse(v.begin() + x + 1, v.begin() + y + 1);
  271. }
  272. }
  273.  
  274. int main()
  275. {
  276. //freopen("in.txt", "r", stdin);
  277.  
  278. cin >> n;
  279. FOR(i, 0, n)
  280. FOR(j, 0, n)
  281. {
  282. // D[i][j] = 1;
  283. cin >> D[i][j];
  284. }
  285.  
  286. vector<int> v;
  287.  
  288. if (n < MAXDP) {
  289. v = solveDP();
  290. }
  291. else
  292. {
  293. v = solve1();
  294.  
  295. BRANCH.init(getScore(v));
  296. VI vBr = BRANCH.solve();
  297. if (vBr.size()==n+1 && getScore(vBr) < getScore(v))v = vBr;
  298. FOR(it, 0, 6000)
  299. {
  300. FOR (it, 0, 1000)
  301. {
  302. optimize2(v);
  303. }
  304. optimize(v);
  305. }
  306. }
  307. cout << getScore(v) << "\n";
  308. FOR(i, 0, SZ(v))cout << v[i] + 1 << " ";
  309.  
  310. // getchar();
  311. // getchar();
  312. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement