mr_dot_convict

753-A-plug-for-unix-UVa-mr.convict

May 31st, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.39 KB | None | 0 0
  1. /*This implementation is using MCBM. For a simple flow implementation see : https://pastebin.com/Dh8eQ2N7 */
  2.  
  3. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  4.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  5.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  6.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  7.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  8. When I wrote this, only God and I understood what I was doing
  9.  ** * * * * * * * Now, only God knows * * * * * * */
  10. #include         <bits/stdc++.h>
  11. using namespace std;
  12. #pragma GCC      optimize ("Ofast")
  13. #pragma GCC      optimize ("unroll-loops")
  14. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  15.  
  16. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  17. #define PREC     cout.precision (10); cout << fixed
  18. #define bg(x)    " [ " << #x << " : " << (x) << " ]"
  19. #define x        first
  20. #define y        second
  21.  
  22. #define debug(args...) { \
  23.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  24.    stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); \
  25. }
  26. void err(istream_iterator<string> it) { it->empty();
  27.    cerr << " (Line : " << __LINE__ << ")" << '\n';
  28. }
  29. template<typename T, typename... Args>
  30. void err(istream_iterator<string> it, T a, Args... args) {
  31.     cerr << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  32.     err(++it, args...);
  33. }
  34.  
  35. const int N = 1000 + 10;
  36. const int infi = (int)1e9;
  37.  
  38. using pss = pair <string, string>;
  39. using pii = pair <int, int>;
  40.  
  41. vector <string> recept;
  42. vector <pss> appliance, adaptor;
  43. int rec, app, adap;
  44. int W[N][N];
  45. map <string, int> adapMap;
  46. int adap_unique_vertices;
  47.  
  48. bool vis[N];
  49. int match[N];
  50. vector < vector <int> > Adj;
  51. int n, nl, nr; // first 0, ..., nl - 1 vertices in left nl, ..., nr - 1 in right
  52.  
  53. void init_mcbm() {
  54.    n = nl + nr;
  55.    assert(n);
  56.    Adj.assign(n, vector <int> ());
  57.    for (int i = 0; i < n; ++i)
  58.       vis[i] = false, match[i] = -1;
  59. }
  60.  
  61. inline void add_edge(int u, int v) {
  62.    Adj[u].push_back(v);
  63. }
  64.  
  65. bool augment(int u) {
  66.    if (vis[u]) return false;
  67.    vis[u] = true;
  68.  
  69.    for (int v : Adj[u]) {
  70.       if (match[v] == -1 || augment(match[v])) {
  71.          match[v] = u;
  72.          return true;
  73.       }
  74.    }
  75.    return false;
  76. }
  77.  
  78. int MCBM() {
  79.    assert (nl + nr == n);
  80.    int mcbm = 0;
  81.  
  82.    for (int u = 0; u < nl; ++u) { // in left set
  83.       fill(vis, vis + n, false);
  84.       mcbm += augment(u);
  85.    }
  86.    return mcbm;
  87. }
  88.  
  89. void init() {
  90.    recept.clear();
  91.    appliance.clear();
  92.    adaptor.clear();
  93.    adapMap.clear();
  94. }
  95.  
  96. void transitive_closure() {
  97.    for (int i = 0; i < adap_unique_vertices; ++i)
  98.       for (int j = 0; j < adap_unique_vertices; ++j)
  99.          W[i][j] = i == j ? 1 : 0;
  100.  
  101.    for (int i = 0; i < adap; ++i) {
  102.       int u = adapMap[adaptor[i].x], v = adapMap[adaptor[i].y];
  103.       W[u][v] = 1;
  104.    }
  105.  
  106.    for (int k = 0; k < adap_unique_vertices; ++k) {
  107.       for (int i = 0; i < adap_unique_vertices; ++i) {
  108.          for (int j = 0; j < adap_unique_vertices; ++j) {
  109.             W[i][j] |= (W[i][k] && W[k][j]);
  110.          }
  111.       }
  112.    }
  113. }
  114.  
  115. void solve() {
  116.    nl = app, nr = rec;
  117.    init_mcbm();
  118.    for (int i = 0; i < rec; ++i) {
  119.       for (int j = 0; j < app; ++j) {
  120.          int u = adapMap[appliance[j].y], v = adapMap[recept[i]];
  121.          if (W[u][v]) add_edge(j, i);
  122.       }
  123.    }
  124.    int mcbm = MCBM();
  125.    cout << app - mcbm << '\n';
  126. }
  127.  
  128. void add_string_in_map(const string &st) {
  129.    if (adapMap.find(st) == adapMap.end())
  130.       adapMap[st] = adap_unique_vertices++;
  131. }
  132.  
  133. void read() {
  134.    init();
  135.    cin >> rec;
  136.    string st_a, st_b;
  137.    adap_unique_vertices = 0;
  138.    for (int i = 0; i < rec; ++i) {
  139.       cin >> st_a;
  140.       recept.push_back(st_a);
  141.       add_string_in_map(st_a);
  142.    }
  143.  
  144.    cin >> app;
  145.    for (int i = 0; i < app; ++i) {
  146.       cin >> st_a >> st_b;
  147.       appliance.push_back(pss(st_a, st_b));
  148.  
  149.       add_string_in_map(st_a);
  150.       add_string_in_map(st_b);
  151.    }
  152.  
  153.    cin >> adap;
  154.    for (int i = 0; i < adap; ++i) {
  155.       cin >> st_a >> st_b;
  156.       adaptor.push_back(pss(st_a, st_b));
  157.  
  158.       add_string_in_map(st_a);
  159.       add_string_in_map(st_b);
  160.    }
  161.    assert ((int) adapMap.size() == adap_unique_vertices);
  162. }
  163.  
  164. signed main() {
  165.    IOS; PREC;
  166.    int tc;
  167.    cin >> tc;
  168.    while (tc--) {
  169.       read();
  170.       transitive_closure();
  171.       solve();
  172.       if (tc) cout << '\n';
  173.    }
  174.  
  175.    return EXIT_SUCCESS;
  176. }
Add Comment
Please, Sign In to add comment