Advertisement
IanisBelu

N. April Fools' Problem (medium)

Oct 29th, 2023
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.98 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 = 2205;
  27. const int PMAX = 10;
  28. const int INF = 2e18+5;
  29.  
  30. struct Edge {
  31.     int dest, cap, cost, other;
  32. };
  33.  
  34. int n, k;
  35. int a[NMAX], b[NMAX];
  36. int source, sink;
  37. vector<Edge> g[NMAX];
  38. int dist[NMAX], pi[NMAX], pi2[NMAX];
  39. int vis[NMAX];
  40. bool inq[NMAX];
  41. pii nxt[NMAX];
  42.  
  43. void add_edge(int x, int y, int cap, int cost) {
  44.     if (!cap) return;
  45.     g[x].push_back({ y, cap, cost, sz(g[y]) });
  46.     g[y].push_back({ x, 0, -cost, sz(g[x]) - 1 });
  47. }
  48.  
  49. void read() {
  50.     cin >> n >> k;
  51.     for (int i = 1; i <= n; i++)
  52.         cin >> a[i];
  53.     for (int i = 1; i <= n; i++)
  54.         cin >> b[i];
  55. }
  56.  
  57. void init_pi() {
  58.     for (int i = 1; i <= n; i++)
  59.         pi[i] = INF;
  60.     pi[source] = 0;
  61.  
  62.     int mn = INF;
  63.     for (int i = 1; i <= n - 2; i++)
  64.         mn = min(mn, a[i]);
  65.     for (int i = 1; i <= n - 2; i++)
  66.         pi[i] = mn;
  67.    
  68.     mn = INF;
  69.     for (int i = n - 2; i >= 1; i--) {
  70.         mn = min(mn, b[i]);
  71.         pi[sink] = min(pi[sink], a[i] + mn);
  72.     }
  73. }
  74.  
  75. void dijkstra() {
  76.     for (int i = 1; i <= n; i++) {
  77.         dist[i] = INF;
  78.         vis[i] = false;
  79.         pi2[i] = pi[i];
  80.     }
  81.  
  82.     priority_queue<pair<ll, int32_t>> pq;
  83.  
  84.     pq.push({0, source});
  85.     dist[source] = pi[source] = 0;
  86.     nxt[source] = {0, 0};
  87.     int32_t i = 0;
  88.  
  89.     while (!pq.empty()) {
  90.         int u = pq.top().se;
  91.  
  92.         pq.pop();
  93.  
  94.         if (vis[u]) continue;
  95.         vis[u] = true;
  96.  
  97.         i = 0;
  98.         for (auto &it : g[u]) {
  99.             if (it.cap && ckmin(dist[it.dest], dist[u] + it.cost + pi2[u] - pi2[it.dest])) {
  100.                 pi[it.dest] = pi[u] + it.cost;
  101.                 nxt[it.dest] = { u, i };
  102.                 pq.push({-dist[it.dest], it.dest});
  103.             }
  104.             i++;
  105.         }
  106.     }
  107. }
  108.  
  109. int mcf(int max_flow) {
  110.     int min_cost = 0;
  111.     init_pi();
  112.     while (dijkstra(), dist[sink] != INF && max_flow) {
  113.         int flow = max_flow, cost = 0;
  114.         for (int u = sink; u != source; u = nxt[u].fi) {
  115.             Edge &e = g[nxt[u].fi][nxt[u].se];
  116.             cost += e.cost;
  117.             ckmin(flow, e.cap);
  118.         }
  119.         for (int u = sink; u != source; u = nxt[u].fi) {
  120.             Edge &e = g[nxt[u].fi][nxt[u].se];
  121.             e.cap -= flow;
  122.             g[u][e.other].cap += flow;
  123.         }
  124.         max_flow -= flow;
  125.         min_cost += flow * cost;
  126.     }
  127.     return min_cost;
  128. }
  129.  
  130. int solve() {
  131.     source = n + 1, sink = n + 2;
  132.     for (int i = 1; i <= n; i++) {
  133.         add_edge(source, i, 1, a[i]);
  134.         add_edge(i, sink, 1, b[i]);
  135.         if (i != n)
  136.             add_edge(i, i + 1, k, 0);
  137.     }
  138.     n += 2;
  139.     return mcf(k);
  140. }
  141.  
  142. signed main() {
  143. #ifdef LOCAL
  144.     freopen("input.txt", "r", stdin);
  145. #else
  146.     ios_base::sync_with_stdio(false);
  147.     cin.tie(0);
  148.     cout.tie(0);
  149. #endif
  150.     read();
  151.     cout << solve() << endl;
  152.     return 0;
  153. }
  154.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement