Advertisement
xosski

Calc(not mine)

Sep 26th, 2024
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.68 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using ll = long long;
  3. #define int long long
  4. #define pb push_back
  5.  
  6. using namespace std;
  7.  
  8. const ll LLINF = 0x3f3f3f3f3f3f3f3f;
  9. const ll INF = 1e18+10;
  10. const int MAX = 5;
  11.  
  12. vector<int> programmer, sports;
  13.  
  14. struct Dinitz {
  15. struct Edge {
  16. int v, u, cap, flow=0, cost;
  17. Edge(int v, int u, int cap, int cost) : v(v), u(u), cap(cap), cost(cost) {}
  18. };
  19.  
  20. int n, s, t;
  21. Dinitz(int n, int s, int t) : n(n), s(s), t(t) {
  22. adj.resize(n);
  23. }
  24.  
  25. int get_cost() {
  26. flow();
  27. return -cost;
  28. }
  29.  
  30. vector<Edge> edges;
  31. vector<vector<int>> adj;
  32. void add_edge(int v, int u, int cap, int cost) {
  33. edges.emplace_back(v, u, cap, cost);
  34. adj[v].pb(edges.size()-1);
  35. edges.emplace_back(u, v, 0, -cost);
  36. adj[u].pb(edges.size()-1);
  37. }
  38.  
  39. vector<int> dist;
  40. bool spfa() {
  41. dist.assign(n, LLINF);
  42.  
  43. queue<int> Q;
  44. vector<bool> inqueue(n, false);
  45.  
  46. dist[s] = 0;
  47. Q.push(s);
  48. inqueue[s] = true;
  49.  
  50. vector<int> cnt(n);
  51.  
  52. while (!Q.empty()) {
  53. int v = Q.front(); Q.pop();
  54. inqueue[v] = false;
  55.  
  56. for (auto eid : adj[v]) {
  57. auto const& e = edges[eid];
  58. if (e.cap - e.flow <= 0) continue;
  59. if (dist[e.u] > dist[e.v] + e.cost) {
  60. dist[e.u] = dist[e.v] + e.cost;
  61. if (!inqueue[e.u]) {
  62. Q.push(e.u);
  63. inqueue[e.u] = true;
  64. }
  65. }
  66. }
  67. }
  68.  
  69. return dist[t] != LLINF;
  70. }
  71.  
  72. int cost = 0;
  73. vector<int> ptr;
  74. int dfs(int v, int f) {
  75. if (v == t || f == 0) return f;
  76. for (auto &cid = ptr[v]; cid < adj[v].size();) {
  77. auto eid = adj[v][cid];
  78. auto &e = edges[eid];
  79. cid++;
  80. if (e.cap - e.flow <= 0) continue;
  81. if (dist[e.v] + e.cost != dist[e.u]) continue;
  82. int newf = dfs(e.u, min(f, e.cap-e.flow));
  83. if (newf == 0) continue;
  84. e.flow += newf;
  85. edges[eid^1].flow -= newf;
  86. cost += e.cost * newf;
  87. return newf;
  88. }
  89. return 0;
  90. }
  91.  
  92. int total_flow = 0;
  93. int flow() {
  94. while (spfa()) {
  95. ptr.assign(n, 0);
  96. while (int newf = dfs(s, LLINF))
  97. total_flow += newf;
  98. }
  99. return total_flow;
  100. }
  101.  
  102. void recover_path() {
  103. for (auto e : edges) {
  104. if (e.v == 1 && e.flow > 0 && e.u > 0) {
  105. programmer.pb(e.u - 2);
  106. }
  107.  
  108.  
  109. if (e.v == 2 && e.flow > 0 && e.u > 0) {
  110. sports.pb(e.u - 2);
  111. }
  112. }
  113. }
  114. };
  115.  
  116. string s;
  117. int n;
  118. vector<int> p;
  119.  
  120. int calc(char c, int j) {
  121. if (s[j] == c && s[n - j - 1] == c) {
  122. return max(p[j], p[n - j - 1]);
  123. }
  124.  
  125. else if (s[j] == c) {
  126. return p[j];
  127. }
  128.  
  129. else if (s[n - j - 1] == c) {
  130. return p[n - j - 1];
  131. }
  132.  
  133. return 0;
  134. }
  135.  
  136. int32_t main() {
  137. ios::sync_with_stdio(false);
  138. cin.tie(NULL);
  139.  
  140. cin >> n;
  141. cin >> s;
  142. p.resize(n);
  143.  
  144. for (int i = 0; i < n; i++) {
  145. cin >> p[i];
  146. }
  147.  
  148. Dinitz dinic = Dinitz(27 + n / 2 + n + 1, 0, 27 + n / 2 + n);
  149.  
  150. map<char, int> amount;
  151. for (int i = 0; i < n; i++) {
  152. amount[s[i]]++;
  153. }
  154.  
  155. for (char c = 'a'; c <= 'z'; c++) {
  156. dinic.add_edge(0, c - 'a' + 1, amount[c], 0);
  157.  
  158. for (int j = 0; j < n / 2; j++) {
  159. dinic.add_edge(c - 'a' + 1, j + 27, 1, -calc(c, j));
  160. }
  161. }
  162.  
  163. for (int j = 0; j < n / 2; j++) {
  164. dinic.add_edge(j + 27, j + 27 + n / 2, 1, 0);
  165. dinic.add_edge(j + 27, 27 + n / 2 + n - j - 1, 1, 0);
  166. }
  167.  
  168. for (int i = 0; i < n; i++) {
  169. dinic.add_edge(27 + n / 2 + i, 27 + n / 2 + n, 1, 0);
  170. }
  171.  
  172. cout << dinic.get_cost() << '\n';
  173.  
  174. return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement