Advertisement
IanisBelu

G. Underfail

Oct 29th, 2023
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.27 KB | Source Code | 0 0
  1. #pragma GCC optimize("Ofast,unroll-loops")
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <queue>
  6. #include <cstring>
  7.  
  8. #define sz(a) ((int)(a).size())
  9. #define all(a) (a).begin(), (a).end()
  10.  
  11. #define fi first
  12. #define se second
  13.  
  14. #define lsb(x) (x & (-x))
  15.  
  16. using namespace std;
  17.  
  18. #define int long long
  19.  
  20. inline bool ckmin(int &a, int b) { if (a <= b) return false; else a = b; return true; }
  21. inline bool ckmax(int &a, int b) { if (a >= b) return false; else a = b; return true; }
  22.  
  23. typedef long long ll;
  24. typedef pair<int, int> pii;
  25.  
  26. const int NMAX = 505;
  27. const int INF = 2e18+5;
  28.  
  29. struct Edge {
  30.     int dest, cap, cost, other;
  31. };
  32.  
  33. int n, m, x;
  34. char s[NMAX];
  35. char a[NMAX][NMAX];
  36. int p[NMAX];
  37. int source, sink;
  38. vector<Edge> g[NMAX];
  39. int dist[NMAX], pi[NMAX], pi2[NMAX];
  40. int vis[NMAX];
  41. bool inq[NMAX];
  42. pii nxt[NMAX];
  43.  
  44. void add_edge(int x, int y, int cap, int cost) {
  45.     if (!cap) return;
  46.     g[x].push_back({ y, cap, cost, sz(g[y]) });
  47.     g[y].push_back({ x, 0, -cost, sz(g[x]) - 1 });
  48. }
  49.  
  50. void read() {
  51.     cin >> n >> (s + 1) >> m;
  52.     for (int i = 1; i <= m; i++)
  53.         cin >> (a[i] + 1) >> p[i];
  54.     cin >> x;
  55. }
  56.  
  57. void init_pi() {
  58.     for (int i = 1; i <= n; i++)
  59.         pi[i] = INF;
  60.     pi[source] = 0;
  61.  
  62.     queue<int32_t> qe;
  63.  
  64.     qe.push(source);
  65.  
  66.     while (!qe.empty()) {
  67.         int u = qe.front();
  68.  
  69.         qe.pop();
  70.         inq[u] = false;
  71.  
  72.         for (auto &it : g[u]) {
  73.             if (it.cap && ckmin(pi[it.dest], pi[u] + it.cost)) {
  74.                 if (!inq[it.dest]) {
  75.                     qe.push(it.dest);
  76.                     inq[it.dest] = true;
  77.                 }
  78.             }
  79.         }
  80.     }
  81. }
  82.  
  83. void dijkstra() {
  84.     for (int i = 1; i <= n; i++) {
  85.         dist[i] = INF;
  86.         vis[i] = false;
  87.         pi2[i] = pi[i];
  88.     }
  89.  
  90.     priority_queue<pair<ll, int32_t>> pq;
  91.  
  92.     pq.push({0, source});
  93.     dist[source] = pi[source] = 0;
  94.     nxt[source] = {0, 0};
  95.     int32_t i = 0;
  96.  
  97.     while (!pq.empty()) {
  98.         int u = pq.top().se;
  99.  
  100.         pq.pop();
  101.  
  102.         if (vis[u]) continue;
  103.         vis[u] = true;
  104.  
  105.         i = 0;
  106.         for (auto &it : g[u]) {
  107.             if (it.cap && ckmin(dist[it.dest], dist[u] + it.cost + pi2[u] - pi2[it.dest])) {
  108.                 pi[it.dest] = pi[u] + it.cost;
  109.                 nxt[it.dest] = { u, i };
  110.                 pq.push({-dist[it.dest], it.dest});
  111.             }
  112.             i++;
  113.         }
  114.     }
  115. }
  116.  
  117. int mcf(int max_flow) {
  118.     int min_cost = 0;
  119.     init_pi();
  120.     while (dijkstra(), dist[sink] != INF && max_flow) {
  121.         int flow = max_flow, cost = 0;
  122.         for (int u = sink; u != source; u = nxt[u].fi) {
  123.             Edge &e = g[nxt[u].fi][nxt[u].se];
  124.             cost += e.cost;
  125.             ckmin(flow, e.cap);
  126.         }
  127.         for (int u = sink; u != source; u = nxt[u].fi) {
  128.             Edge &e = g[nxt[u].fi][nxt[u].se];
  129.             e.cap -= flow;
  130.             g[u][e.other].cap += flow;
  131.         }
  132.         max_flow -= flow;
  133.         min_cost += flow * cost;
  134.     }
  135.     return min_cost;
  136. }
  137.  
  138. int solve() {
  139.     source = n + 1, sink = n + 2;
  140.     add_edge(source, 1, x, 0);
  141.     for (int i = 1; i < n; i++)
  142.         add_edge(i, i + 1, x, 0);
  143.     add_edge(n, sink, x, 0);
  144.     for (int j = 1; j <= m; j++) {
  145.         int l = strlen(a[j] + 1);
  146.         for (int i = 1; i <= n - l + 1; i++) {
  147.             if (strncmp(s + i, a[j] + 1, l) == 0) {
  148.                 if (i == n - l + 1) add_edge(i, sink, 1, -p[j]);
  149.                 else add_edge(i, i + l, 1, -p[j]);
  150.             }
  151.         }
  152.     }
  153.     n += 2;
  154.     return -mcf(INF);
  155. }
  156.  
  157. signed main() {
  158. #ifdef LOCAL
  159.     freopen("input.txt", "r", stdin);
  160. #else
  161.     ios_base::sync_with_stdio(false);
  162.     cin.tie(0);
  163.     cout.tie(0);
  164. #endif
  165.     read();
  166.     cout << solve() << endl;
  167.     return 0;
  168. }
  169.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement