Advertisement
GerONSo

7 ЛКШ

Apr 11th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.81 KB | None | 0 0
  1. // #define pragma
  2.  
  3. #ifdef pragma
  4. #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
  5. // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  6. #endif // pragma
  7.  
  8. #include<bits/stdc++.h>
  9. #include <ext/pb_ds/assoc_container.hpp>
  10. #include <ext/pb_ds/tree_policy.hpp>
  11.  
  12. #define ll long long
  13. #define all(x) begin(x), end(x)
  14. #define pb push_back
  15. #define x first
  16. #define y second
  17. #define int long long
  18. #define zero(two) memset(two, 0, sizeof(two))
  19.  
  20. using namespace std;
  21. using namespace __gnu_pbds;
  22.  
  23.  
  24. typedef vector<int> vi;
  25. typedef vector<bool> vb;
  26. typedef pair<int, int> pii;
  27. typedef long double ld;
  28. typedef vector<vi> matrix;
  29. template<typename T>
  30. using kawaii_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
  31.  
  32. const ld PI = atan2(0, -1);
  33.  
  34. void seriy() {
  35. ios::sync_with_stdio(0);
  36. cin.tie(0);
  37. cout.tie(0);
  38. // cout << fixed << setprecision(10);
  39. #if 1
  40. freopen("input", "r", stdin);
  41. freopen("output", "w", stdout);
  42. #endif
  43. }
  44.  
  45. const int MAXN = 50 + 10;
  46. const int INF = 1e15 + 7;
  47. const int MAXLOG = 31;
  48. const int MOD = 998244353;
  49. const int BASE = 47;
  50.  
  51. struct node {
  52. int x, y, cnt, isl;
  53. };
  54.  
  55. struct edge {
  56. int u, v, w;
  57. };
  58.  
  59. bool used2[MAXN][MAXN];
  60. int dx[4] = {-1, 1, 0, 0};
  61. int dy[4] = {0, 0, -1, 1};
  62. char c[MAXN][MAXN];
  63. int n, m, ans = 0;
  64. int d[MAXN][MAXN];
  65. int cur = 0;
  66. vb kek(MAXN);
  67. vector<pii> st;
  68. vector<vector<pii>> g;
  69. vi pr(MAXN), sz(MAXN);
  70. vector<pii> ed(MAXN);
  71.  
  72. int get(int a) {
  73. if(a == pr[a]) return a;
  74. return pr[a] = get(pr[pr[a]]);
  75. }
  76.  
  77. void unite(int a, int b) {
  78. int pa = a, pb = b;
  79. a = get(a);
  80. b = get(b);
  81. if(a != b) {
  82. if(sz[a] < sz[b]) {
  83. swap(a, b);
  84. }
  85. if(ed[a].x == pa && ed[b].x == pb) {
  86. ed[a].x = ed[a].y;
  87. ed[a].y = ed[b].y;
  88. }
  89. else if(ed[a].y == pa && ed[b].x == pb) {
  90. ed[a].x = ed[a].x;
  91. ed[a].y = ed[b].y;
  92. }
  93. else if(ed[a].x == pa && ed[b].y == pb) {
  94. ed[a].x = ed[a].y;
  95. ed[a].y = ed[b].x;
  96. }
  97. else {
  98. ed[a].x = ed[a].x;
  99. ed[a].y = ed[b].x;
  100. }
  101. pr[b] = a;
  102. sz[a] += sz[b];
  103. }
  104. }
  105.  
  106. void dfs(int x, int y) {
  107. used2[x][y] = 1;
  108. for(int k = 0; k < 4; k++) {
  109. int tox = x + dx[k];
  110. int toy = y + dy[k];
  111. if(tox >= 0 && tox < n && toy >= 0 && toy < m && !used2[tox][toy] && c[tox][toy] == 'X') {
  112. dfs(tox, toy);
  113. }
  114. }
  115. }
  116.  
  117.  
  118. bool cmp(edge a, edge b) {
  119. return a.w < b.w;
  120. }
  121.  
  122. signed main() {
  123. seriy();
  124. cin >> n >> m;
  125.  
  126. for(int i = 0; i < n; i++) {
  127. for(int j = 0; j < m; j++) {
  128. cin >> c[i][j];
  129. }
  130. }
  131. int cnt = 0;
  132. map<pii, int> mp;
  133. for(int i = 0; i < n; i++) {
  134. for(int j = 0; j < m; j++) {
  135. if(!used2[i][j] && c[i][j] == 'X') {
  136. st.pb({i, j});
  137. dfs(i, j);
  138. cnt++;
  139. mp[{i, j}] = cnt;
  140. }
  141. }
  142. }
  143. // cerr << 1;
  144. fill(&d[0][0], &d[0][0] + MAXN * MAXN, INF);
  145. for(int i = 0; i < st.size(); i++) {
  146. pr[i] = i;
  147. ed[i] = {i, i};
  148. // cerr << i << '\n';
  149. deque<node> q;
  150. // cerr << st[i].x << " " << st[i].y << " ";
  151. q.push_back({st[i].x, st[i].y, 0, 1});
  152. bool used[n][m];
  153. zero(used);
  154. used[st[i].x][st[i].y] = 1;
  155. while(!q.empty()) {
  156. node u = q.front();
  157. q.pop_front();
  158. if(mp[{u.x, u.y}]) {
  159. // cerr << u.x << " " << u.y << " " << u.cnt << " ";
  160. // cerr << i << " " << mp[{u.x, u.y}] - 1 << " " << u.cnt << '\n';
  161. d[i][mp[{u.x, u.y}] - 1] = min(d[i][mp[{u.x, u.y}] - 1], u.cnt);
  162. // if(i != mp[{u.x, u.y}] - 1) continue;
  163. }
  164. for(int k = 0; k < 4; k++) {
  165. int tox = u.x + dx[k];
  166. int toy = u.y + dy[k];
  167. if(tox >= 0 && tox < n && toy >= 0 && toy < m && !used[tox][toy] && c[tox][toy] != '.') {
  168. used[tox][toy] = 1;
  169. if(c[tox][toy] == 'S') {
  170. q.push_back({tox, toy, u.cnt + 1, u.isl});
  171. }
  172. else {
  173. int isl = u.isl;
  174. if(c[u.x][u.y] == 'S' && c[tox][toy] == 'X') {
  175. isl = u.isl + 1;
  176. }
  177. q.push_front({tox, toy, u.cnt, isl});
  178. }
  179. }
  180. }
  181. }
  182. // cerr << '\n';
  183. }
  184. // cerr << 1;
  185. g.resize(st.size());
  186. vector<edge> edges;
  187. // cerr << '\n';
  188. for(int i = 0; i < st.size(); i++) {
  189. for(int j = 0; j < st.size(); j++) {
  190. // cerr << d[i][j] << " ";
  191. if(i == j || d[i][j] == INF) continue;
  192. // edges.pb({i, j, d[i][j]});
  193. g[i].pb({j, d[i][j]});
  194. // cerr << i << " " << j << " " << d[i][j] << '\n';
  195. }
  196. // cerr << '\n';
  197. }
  198. int dp[(1ll << 17)][st.size()];
  199. for(int i = 0; i < (1ll << 17); i++) {
  200. for(int j = 0; j < st.size(); j++) {
  201. dp[i][j] = INF;
  202. if((i ^ (1ll << j)) == 0) dp[i][j] = 0;
  203. }
  204. }
  205. for(int i = 0; i < (1ll << 17); i++) {
  206. for(int j = 0; j < st.size(); j++) {
  207. if(((1ll << j) & i) && (i & (i - 1)) > 0) {
  208. for(auto k : g[j]) {
  209. dp[i][j] = min(dp[i][j], dp[(i ^ (1ll << j))][k.x] + d[k.x][j]);
  210. }
  211. }
  212. }
  213. }
  214. int ans = INF;
  215. for(int i = 0; i < st.size(); i++) {
  216. ans = min(ans, dp[(1ll << (st.size())) - 1][i]);
  217. }
  218. cout << ans;
  219. return 0;
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement