Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.92 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <cstdio>
  3. #include <vector>
  4. #include <string>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <map>
  8. #include <iterator>
  9. #include <functional>
  10. #include <set>
  11. #include <stack>
  12. #include <queue>
  13. #include <deque>
  14. #include <fstream>
  15. #include <iomanip>
  16. #include <numeric>
  17. #include <cmath>
  18. #include <list>
  19. #include <sstream>
  20. #include <cstring>
  21. #include <stdio.h>
  22. #include <bitset>
  23. #include <complex>
  24. #include <cassert>
  25. using namespace std;
  26. #pragma GCC optimize("O3")
  27. #pragma GCC target("sse4")
  28.  
  29. typedef double LD;
  30. typedef long long LL;
  31. typedef pair<int, int> PII;
  32. typedef pair<LD, LD> PDD;
  33. typedef pair<LL, LL> PLL;
  34. typedef vector<int> VI;
  35. typedef vector<LL> VLL;
  36. typedef vector<LD> VLD;
  37. typedef vector<string> VS;
  38. typedef vector<PII> VPII;
  39. typedef vector<PLL> VPLL;
  40. #define MP make_pair
  41. #define PB push_back
  42. #define X first
  43. #define Y second
  44. #define prev fake_prev
  45. #define left fake_left
  46. #define right fake_right
  47.  
  48. #define FOR(i, a, b) for(int i = (a); i < (b); ++i)
  49. #define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
  50. #define REP(i, t) FOR(i, 0, t)
  51. #define ALL(a) a.begin(), a.end()
  52. #define SZ(a) (int)((a).size())
  53. #define FILL(a, value) memset(a, value, sizeof(a))
  54.  
  55. const LD PI = acos(-1.0);
  56. const LD EPS = 1e-7;
  57. const LL INF = 1e9 + 47;
  58. const LL LINF = 1e18;
  59. const LL mod = 1e9 + 7;
  60. const LL MAX = 400;
  61.  
  62. int n;
  63. int d[MAX][MAX];
  64. char used[MAX];
  65.  
  66. pair<int, VI> greedy()
  67. {
  68. FILL(used, 0);
  69. used[0] = 1;
  70. int ans = 0;
  71. int curr = 0;
  72. VI res;
  73. res.push_back(0);
  74.  
  75. while (1)
  76. {
  77. bool ok = 0;
  78. FOR(i, 0, n)
  79. if (used[i] == 0)
  80. ok = 1;
  81.  
  82. if (!ok)
  83. {
  84. ans += d[curr][0];
  85. res.push_back(0);
  86. break;
  87. }
  88.  
  89. int best = -1;
  90. FOR(i, 0, n)
  91. {
  92. if (used[i])
  93. continue;
  94. if (best == -1 || d[curr][best] > d[curr][i])
  95. best = i;
  96. }
  97.  
  98. ans += d[curr][best];
  99. res.push_back(best);
  100. curr = best;
  101. used[best] = 1;
  102. }
  103.  
  104. return MP(ans, res);
  105. }
  106.  
  107. const int M = 20;
  108. int DP[1 << M][M];
  109.  
  110. int solve(int mask, int now)
  111. {
  112. if (DP[mask][now] != -1)
  113. return DP[mask][now];
  114.  
  115. int res = INF;
  116. FOR(i, 0, n)
  117. {
  118. if (mask & (1 << i))
  119. continue;
  120.  
  121. res = min(res, d[now][i] + solve(mask | (1 << i), i));
  122. }
  123.  
  124. if (res == INF)
  125. res = d[now][0];
  126.  
  127. return DP[mask][now] = res;
  128. }
  129.  
  130. void brute()
  131. {
  132. assert(n > 1);
  133. FILL(DP, -1);
  134. int best = -1, ans = INF;
  135. FOR(i, 1, n)
  136. {
  137. int r = solve(1 + (1 << i), i) + d[0][i];
  138. if (r < ans)
  139. {
  140. ans = r;
  141. best = i;
  142. }
  143. }
  144.  
  145. cout << ans << endl;
  146. VI path;
  147.  
  148. path.push_back(0);
  149. path.push_back(best);
  150. int curr = 1 + (1 << best);
  151.  
  152. while (curr != (1 << n) - 1)
  153. {
  154. FOR(i, 0, n)
  155. {
  156. if (curr & (1 << i))
  157. continue;
  158.  
  159. bool ok = 0;
  160.  
  161. if (solve(curr | (1 << i), i) == solve(curr, best) - d[best][i])
  162. ok = 1;
  163.  
  164. if (ok)
  165. {
  166. curr |= (1 << i);
  167. best = i;
  168. path.push_back(best);
  169. break;
  170. }
  171. }
  172. }
  173.  
  174. path.push_back(0);
  175. FOR(i, 0, SZ(path))
  176. {
  177. if (i)
  178. cout << " ";
  179. cout << path[i] + 1;
  180. }
  181.  
  182. exit(0);
  183. }
  184.  
  185. pair<int, VI> combine()
  186. {
  187. int old = n;
  188. n = M;
  189. FILL(DP, -1);
  190. int best = -1, ans = INF;
  191. FOR(i, 1, n)
  192. {
  193. int r = solve(1 + (1 << i), i) + d[0][i];
  194. if (r < ans)
  195. {
  196. ans = r;
  197. best = i;
  198. }
  199. }
  200.  
  201. VI path;
  202. used[0] = used[best] = 1;
  203.  
  204. path.push_back(0);
  205. path.push_back(best);
  206. int curr = 1 + (1 << best);
  207.  
  208. while (curr != (1 << n) - 1)
  209. {
  210. FOR(i, 0, n)
  211. {
  212. if (curr & (1 << i))
  213. continue;
  214.  
  215. bool ok = 0;
  216.  
  217. if (solve(curr | (1 << i), i) == solve(curr, best) - d[best][i])
  218. ok = 1;
  219.  
  220. if (ok)
  221. {
  222. curr |= (1 << i);
  223. best = i;
  224. used[best] = 1;
  225. path.push_back(best);
  226. break;
  227. }
  228. }
  229. }
  230.  
  231. curr = path.back();
  232. n = old;
  233. while (1)
  234. {
  235. bool ok = 0;
  236. FOR(i, 0, n)
  237. if (used[i] == 0)
  238. ok = 1;
  239.  
  240. if (!ok)
  241. {
  242. ans += d[curr][0];
  243. path.push_back(0);
  244. break;
  245. }
  246.  
  247. int best = -1;
  248. FOR(i, 0, n)
  249. {
  250. if (used[i])
  251. continue;
  252. if (best == -1 || d[curr][best] > d[curr][i])
  253. best = i;
  254. }
  255.  
  256. ans += d[curr][best];
  257. path.push_back(best);
  258. curr = best;
  259. used[best] = 1;
  260. }
  261.  
  262.  
  263. return MP(ans, path);
  264. }
  265.  
  266. int main()
  267. {
  268. ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  269. //freopen("In.txt", "r", stdin);
  270.  
  271. clock_t cl = clock();
  272. cin >> n;
  273. FOR(i, 0, n)
  274. FOR(j, 0, n)
  275. cin >> d[i][j];
  276.  
  277. if (n <= M)
  278. brute();
  279.  
  280. srand(time(NULL) ^ mod);
  281. pair<int, VI> ans = greedy();
  282. pair<int, VI> cmb = combine();
  283. if (cmb.X > ans.X)
  284. ans = cmb;
  285.  
  286. VI per;
  287. FOR(i, 0, n)
  288. per.push_back(i);
  289.  
  290. while (clock() - cl >= CLOCKS_PER_SEC * 0.97)
  291. {
  292. random_shuffle(ALL(per));
  293. int cnt = d[per[n - 1]][per[0]];
  294. FOR(i, 0, n - 1)
  295. cnt += d[per[i]][per[i + 1]];
  296.  
  297. if (cnt < ans.X)
  298. {
  299. ans.X = cnt;
  300. ans.Y = per;
  301. ans.Y.push_back(per[0]);
  302. }
  303. }
  304.  
  305. cout << ans.X << endl;
  306. FOR(i, 0, SZ(ans.Y))
  307. {
  308. if (i)
  309. cout << " ";
  310. cout << ans.Y[i] + 1;
  311. }
  312.  
  313. cin >> n;
  314. return 0;
  315. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement