mr_dot_convict

753-A-plug-for-unix (flow implementation)-UVa-mr.convict

May 31st, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.39 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include         <bits/stdc++.h>
  9. using namespace std;
  10. #pragma GCC      optimize ("Ofast")
  11. #pragma GCC      optimize ("unroll-loops")
  12. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  13.  
  14. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  15. #define PREC     cout.precision (10); cout << fixed
  16. #define bg(x)    " [ " << #x << " : " << (x) << " ]"
  17. #define x        first
  18. #define y        second
  19.  
  20. #define debug(args...) { \
  21.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  22.    stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); \
  23. }
  24. void err(istream_iterator<string> it) { it->empty();
  25.    cerr << " (Line : " << __LINE__ << ")" << '\n';
  26. }
  27. template<typename T, typename... Args>
  28. void err(istream_iterator<string> it, T a, Args... args) {
  29.     cerr << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  30.     err(++it, args...);
  31. }
  32. const int N = 100 + 2 * 100 + 100 + 2;
  33. const int infi = (int)1e9;
  34.  
  35. using pss = pair <string, string>;
  36. using pii = pair <int, int>;
  37.  
  38. vector <string> recept;
  39. vector <pss> appliance, adaptor;
  40. int rec, app, adap;
  41.  
  42. vector < vector <int> > Adj;
  43. vector <pii> cutEdges;
  44. bool inS[N];
  45. int Par[N];
  46. int cap[N][N], fcap[N][N];
  47. int n, m;
  48.  
  49. void init () {
  50.    assert(n);
  51.    Adj.assign(n, vector <int> ());
  52.    for (int i = 0; i < n; ++i)
  53.       for (int j = 0; j < n; ++j)
  54.          fcap[i][j] = cap[i][j] = 0;
  55.    cutEdges.clear();
  56.    fill (inS, inS + n, false);
  57. }
  58.  
  59. int bfs (const int &s, const int &t) {
  60.    fill (Par, Par + n, -1);
  61.    Par[s] = -2;
  62.  
  63.    queue <pii> Q;
  64.    Q.push(pii(s, infi));
  65.  
  66.    while (!Q.empty()) {
  67.       pii tmp = Q.front();
  68.       Q.pop();
  69.       int u = tmp.x, flow = tmp.y;
  70.  
  71.       for (int v : Adj[u]) {
  72.          if (Par[v] == -1 && fcap[u][v]) {
  73.             Par[v] = u;
  74.             int newFlow = min(flow, fcap[u][v]);
  75.             if (v == t) {
  76.                return newFlow;
  77.             }
  78.             Q.push(pii(v, newFlow));
  79.          }
  80.       }
  81.    }
  82.    return 0;
  83. }
  84.  
  85. int edmondsKarpMaxFlow(const int &s, const int &t, const int &K = infi) {
  86.    for (int i = 0; i < n; ++i)
  87.       for (int j = 0; j < n; ++j)
  88.          fcap[i][j] = cap[i][j];
  89.  
  90.    int flow = 0;
  91.    int newFlow;
  92.  
  93.    while ((newFlow = bfs (s, t)) && flow < K) {
  94.       newFlow = min(newFlow, K - flow);
  95.       flow += newFlow;
  96.       int cur = t;
  97.       while (cur != s) {
  98.          int prv = Par[cur];
  99.          fcap[prv][cur] -= newFlow;
  100.          fcap[cur][prv] += newFlow;
  101.          cur = prv;
  102.       }
  103.    }
  104.  
  105.    assert (flow < K);
  106.    // assert (flow != 0);
  107.    return flow;
  108. }
  109.  
  110. void dfs(int u) {
  111.    inS[u] = true;
  112.    for (int v : Adj[u])
  113.       if (!inS[v]) dfs(v);
  114. }
  115.  
  116. void findCutEdges() {
  117.    cutEdges.clear();
  118.    for (int u = 0; u < n; ++u) {
  119.       if (!inS[u]) continue;
  120.       for (int v : Adj[u]) {
  121.          if (inS[v]) continue;
  122.          if (fcap[u][v] == 0) cutEdges.push_back(pii(u, v));
  123.       }
  124.    }
  125. }
  126.  
  127. inline void add_edge (int u, int v, int flow) {
  128.    Adj[u].push_back(v);
  129.    Adj[v].push_back(u);
  130.    cap[u][v] = flow;
  131. }
  132. void v_init() {
  133.    recept.clear();
  134.    appliance.clear();
  135.    adaptor.clear();
  136. }
  137.  
  138. int s, t;
  139. void solve() {
  140.    int flow = edmondsKarpMaxFlow(s, t);
  141.    cout << app - flow << '\n';
  142. }
  143.  
  144. void create_edges() {
  145.    n = rec + app + 2 * adap + 2;
  146.    s = n - 2, t = n - 1;
  147.    init();
  148.  
  149.    // edges for receptacle with target
  150.    for (int i = 0; i < rec; ++i)
  151.       add_edge (i, t, 1);
  152.  
  153.  
  154.    /****BE AWARE>>>>adapters are infinite so you can take as many*****/
  155.    // edge for adaptor among themselves
  156.    for (int i = 0; i < adap; ++i) {
  157.       add_edge (2 * i + rec, 2 * i + 1 + rec, infi);
  158.  
  159.       for (int j = 0; j < adap; ++j) {
  160.          if (i == j) continue;
  161.          if (adaptor[i].y == adaptor[j].x)
  162.             add_edge (2 * i + 1 + rec, 2 * j + rec, infi);
  163.       }
  164.    }
  165.  
  166.    // edge for adaptors and receptacles
  167.    for (int i = 0; i < adap; ++i) {
  168.       for (int j = 0; j < rec; ++j) {
  169.          if (adaptor[i].y == recept[j]) add_edge (2 * i + 1 + rec, j, infi);
  170.       }
  171.    }
  172.  
  173.    // edges for appliance
  174.    for (int i = 0; i < app; ++i) {
  175.       add_edge (s, i + rec + 2 * adap, 1);
  176.  
  177.       for (int j = 0; j < rec; ++j) {
  178.          if (appliance[i].y == recept[j]) add_edge (i + rec + 2 * adap, j, infi);
  179.       }
  180.  
  181.       for (int j = 0; j < adap; ++j) {
  182.          if (appliance[i].y == adaptor[j].x) add_edge(i + rec + 2 * adap, 2 * j + rec, infi);
  183.       }
  184.    }
  185. }
  186.  
  187. void read() {
  188.    v_init();
  189.    cin >> rec;
  190.    string st_a, st_b;
  191.    for (int i = 0; i < rec; ++i) {
  192.       cin >> st_a;
  193.       recept.push_back(st_a);
  194.    }
  195.  
  196.    cin >> app;
  197.    for (int i = 0; i < app; ++i) {
  198.       cin >> st_a >> st_b;
  199.       appliance.push_back(pss(st_a, st_b));
  200.    }
  201.  
  202.    cin >> adap;
  203.    for (int i = 0; i < adap; ++i) {
  204.       cin >> st_a >> st_b;
  205.       adaptor.push_back(pss(st_a, st_b));
  206.    }
  207. }
  208.  
  209. signed main() {
  210.    IOS; PREC;
  211.    int tc;
  212.    cin >> tc;
  213.    while (tc--) {
  214.       read();
  215.       create_edges();
  216.       solve();
  217.       if (tc) cout << '\n';
  218.    }
  219.  
  220.    return EXIT_SUCCESS;
  221. }
Add Comment
Please, Sign In to add comment