Advertisement
IanisBelu

Transportation Delegation

Oct 9th, 2023
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.44 KB | Source Code | 0 0
  1. #pragma GCC optimize("Ofast,unroll-loops")
  2. #include <bits/stdc++.h>
  3.  
  4. #define sz(a) ((int)(a).size())
  5. #define all(a) (a).begin(), (a).end()
  6.  
  7. #define fi first
  8. #define se second
  9.  
  10. using namespace std;
  11.  
  12. #ifndef LOCAL
  13. #define endl '\n'
  14. #endif
  15.  
  16. typedef long long ll;
  17. typedef pair<int, int> pii;
  18.  
  19. const int NMAX = 4005;
  20. const int INF = 2e9+5;
  21.  
  22. struct Edge {
  23.     int dest, flow, rev;
  24. };
  25.  
  26. int n, s, r, f, t;
  27. vector<Edge> g[NMAX];
  28. int d[NMAX], last[NMAX];
  29. unordered_map<string, int> mp;
  30. vector<int> v[NMAX];
  31.  
  32. void io() {
  33. #ifdef LOCAL
  34.     freopen("input.txt", "r", stdin);
  35. #else
  36.     ios_base::sync_with_stdio(false);
  37.     cin.tie(0);
  38.     cout.tie(0);
  39. #endif
  40. }
  41.  
  42. void read() {
  43.     cin >> s >> r >> f >> t;
  44.     string str;
  45.     for (int i = 1; i <= r; i++) {
  46.         cin >> str;
  47.         mp[str] = i;
  48.     }
  49.     for (int i = 1; i <= f; i++) {
  50.         cin >> str;
  51.         mp[str] = r + i;
  52.     }
  53.     n = r + f;
  54.     for (int i = 1, cnt; i <= t; i++) {
  55.         cin >> cnt;
  56.         v[i].reserve(cnt);
  57.         while (cnt--) {
  58.             cin >> str;
  59.             if (mp[str] == 0)
  60.                 mp[str] = ++n;
  61.             v[i].push_back(mp[str]);
  62.         }
  63.     }
  64. }
  65.  
  66. void add_edge(int x, int y, int c) {
  67.     g[x].push_back({ y, c, sz(g[y]) });
  68.     g[y].push_back({ x, 0, sz(g[x]) - 1 });
  69. }
  70.  
  71. void precalc() {
  72.     for (int i = 1; i <= t; i++) {
  73.         add_edge(n + 1, n + 2, 1);
  74.         n += 2;
  75.     }
  76.     for (int i = 1; i <= t; i++) {
  77.         for (auto &it : v[i]) {
  78.             add_edge(it, s + (i << 1) - 1, 1);
  79.             if (it > r)
  80.                 add_edge(s + (i << 1), it, 1);
  81.         }
  82.     }
  83.     n++;
  84.     for (int i = 1; i <= r; i++)
  85.         add_edge(0, i, 1);
  86.     for (int i = 1; i <= f; i++)
  87.         add_edge(r + i, n, 1);
  88. }
  89.  
  90. bool bfs() {
  91.     memset(d, 0, sizeof(d));
  92.     memset(last, 0, sizeof(last));
  93.  
  94.     queue<int> q;
  95.     q.push(0);
  96.     d[0] = 1;
  97.  
  98.     while (!q.empty()) {
  99.         int u = q.front();
  100.         q.pop();
  101.         if (u == n) continue;
  102.         for (auto &it : g[u]) {
  103.             if (!d[it.dest] && it.flow > 0) {
  104.                 d[it.dest] = d[u] + 1;
  105.                 q.push(it.dest);
  106.             }
  107.         }
  108.     }
  109.  
  110.     return d[n];
  111. }
  112.  
  113. int dfs(int x = 0, int flow = INF) {
  114.     if (x == n) return flow;
  115.  
  116.     for (; last[x] < sz(g[x]); last[x]++) {
  117.         Edge &e = g[x][last[x]];
  118.         if (e.flow > 0 && d[e.dest] == d[x] + 1) {
  119.             if (int ret = dfs(e.dest, min(flow, e.flow))) {
  120.                 e.flow -= ret;
  121.                 g[e.dest][e.rev].flow += ret;
  122.                 return ret;
  123.             }
  124.         }
  125.     }
  126.  
  127.     return 0;
  128. }
  129.  
  130. int dinic() {
  131.     int max_flow = 0;
  132.     while (bfs()) {
  133.         while (int flow = dfs())
  134.             max_flow += flow;
  135.     }
  136.     return max_flow;
  137. }
  138.  
  139. signed main() {
  140.     io();
  141.     read();
  142.     precalc();
  143.     cout << dinic() << endl;
  144.     return 0;
  145. }
  146.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement