Guest User

Untitled

a guest
Jan 23rd, 2018
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.47 KB | None | 0 0
  1. using namespace std;
  2.  
  3. #include <algorithm>
  4. #include <cctype>
  5. #include <cmath>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <cstring>
  9. #include <iostream>
  10. #include <limits>
  11. #include <map>
  12. #include <queue>
  13. #include <set>
  14. #include <sstream>
  15. #include <stack>
  16. #include <string>
  17. #include <vector>
  18.  
  19. #define EPS 1e-11
  20. #define inf ( 1LL << 31 ) - 1
  21. #define LL long long
  22.  
  23. #define _rep( i, a, b, x ) for( __typeof(b) i = ( a ); i <= ( b ); i += x )
  24. #define rep( i, n ) _rep( i, 0, n - 1, 1 )
  25. #define rrep( i, a, b ) for( __typeof(b) i = ( a ); i >= ( b ); --i )
  26. #define xrep( i, a, b ) _rep( i, a, b, 1 )
  27.  
  28. #define abs(x) (((x)< 0) ? (-(x)) : (x))
  29. #define all(x) (x).begin(), (x).end()
  30. #define ms(x, a) memset((x), (a), sizeof(x))
  31. #define mp make_pair
  32. #define pb push_back
  33. #define sz(k) (int)(k).size()
  34.  
  35. typedef vector <int> vi;
  36.  
  37.  
  38.  
  39.  
  40. // dinic algorithm
  41. /* notes
  42.     source sink : 0 based
  43.     no of edges will always be double of no of edges in the network
  44.     change the value of data accoring to data type
  45. */
  46. struct dinic
  47. {
  48.     int n, m, s, t, head, tail, ne;
  49.     #define data int // change int -> LL if needed
  50.     data data_inf;
  51.     int *to, *next, *last, *d, *q, *now, *invalid, *cantuse;
  52.     data *cap;
  53.     dinic() {}
  54.     dinic(int xn, int xm)
  55.     {
  56.         n = xn; m = xm; ne = 0;
  57.         to = new int[m]; cap = new data[m]; next = new int[m];
  58.         d = new int[n]; q = new int[n+n]; now = new int[n]; last = new int[n]; invalid = new int[n], cantuse = new int[m];
  59.         fill(last, last+n, -1);
  60.         fill(invalid, invalid+n, 0);
  61.         fill(cantuse, cantuse+n, 0);
  62.     }
  63.     void clear() { ne = 0; fill(last, last+n, -1); }
  64.     inline void add_edge(int u, int v, data uv, data vu)
  65.     {
  66.         to[ne] = v; cap[ne] = uv; next[ne] = last[u]; last[u] = ne++;
  67.         to[ne] = u; cap[ne] = vu; next[ne] = last[v]; last[v] = ne++;
  68.     }
  69.     inline bool bfs()
  70.     {
  71.         fill(d, d+n, -1);
  72.         head = tail = 0;
  73.         d[t] = 0;
  74.         q[tail++] = t;
  75.         int u, v, e;
  76.         while (head < tail)
  77.         {
  78.             u = q[head++];
  79.             if (invalid[u]) continue;
  80.             for (e = last[u]; e != -1; e = next[e])
  81.             {
  82.                 if (cantuse[e]) continue;
  83.                 v = to[e];
  84.                 if (invalid[v]) continue;
  85.                 if (cap[e^1] > 0 && d[v] == -1)
  86.                 {
  87.                     q[tail++] = v;
  88.                     d[v] = d[u] + 1;
  89.                 }
  90.             }
  91.  
  92.         }
  93.         return d[s] != -1;
  94.     }
  95.     data dfs(int u, data f)
  96.     {
  97.         if (u == t) return f;
  98.         int v;
  99.         data ret;
  100.         for (int &e = now[u]; e != -1; e = next[e])
  101.         {
  102.             if (cantuse[e]) continue;
  103.             v = to[e];
  104.             if (invalid[v]) continue;
  105.             if (cap[e] > 0 && d[u] == d[v] + 1)
  106.             {
  107.                 ret = dfs(v, min(f, cap[e]));
  108.                 if (ret > 0)
  109.                 {
  110.                     cap[e] -= ret;
  111.                     cap[e^1] += ret;
  112.                     return ret;
  113.                 }
  114.  
  115.             }
  116.         }
  117.         return 0;
  118.     }
  119.  
  120.     data maxflow(int source, int sink, int N)
  121.     {
  122.         s = source; t = sink;
  123.         data f = 0, x;
  124.         data_inf = numeric_limits<data>::max();
  125.         while (bfs())
  126.         {
  127.             rep(i,n) now[i] = last[i];
  128.             while (true)
  129.             {
  130.                 x = dfs(s, data_inf);
  131.                 if (x == 0) break;
  132.                 f = f + x;
  133.             }
  134.         }
  135.  
  136.         return f;
  137.     }
  138.  
  139. } G(150, 150*150);
  140. const int MAXN = 70;
  141. const int MAXM = 70;
  142. int spot[MAXM];
  143. int K[MAXN];
  144. int pref[MAXN][MAXN];
  145. int assign[MAXN];
  146. int used[MAXM];
  147.  
  148. int main()
  149. {
  150.     #ifdef Local
  151.         freopen("/home/wasi/Desktop/input.txt", "r", stdin);
  152.     #endif
  153.     int t, n, m, tcase = 1;
  154.     scanf("%d", &t);
  155.     while (t--)
  156.     {
  157.         scanf("%d %d", &n, &m);
  158.         rep(i,m) scanf("%d", &spot[i]);
  159.         rep(i,n)
  160.         {
  161.             scanf("%d",&K[i]);
  162.             rep(j,K[i])
  163.             {
  164.                 scanf("%d", &pref[i][j]);
  165.                 pref[i][j]--;
  166.             }
  167.         }
  168.         G.clear();
  169.         int source = n+m, sink = n+m+1, BIG = G.data_inf;
  170.         rep(i,n) G.add_edge(source, i, 1, 0);
  171.         rep(i,n) rep(j,K[i])
  172.             G.add_edge(i, pref[i][j]+n, 1, 0);
  173.         rep(i,m) G.add_edge(i+n, sink, spot[i], 0);
  174.  
  175.         int F = G.maxflow(source, sink, n+m+2), NF;
  176.  
  177.         printf("Case #%d:\n%d applicant(s) can be hired.\n", tcase++, F);
  178.  
  179.         rep(i,n) assign[i] = -1;
  180.         rep(i,n)
  181.         {
  182.             rep(j,K[i])
  183.             {
  184.                 int job = pref[i][j];
  185.                 if (spot[job] == 0) continue;
  186.                 spot[job]--;
  187.                 G.clear();
  188.                 rep(x,n) if (assign[x] == -1 && x != i) G.add_edge(source, x, 1, 0);
  189.                 rep(x,n) rep(y,K[x])
  190.                 {
  191.                     if (assign[x] != -1) continue;
  192.                     if (x == i) continue;
  193.                     G.add_edge(x, pref[x][y]+n, 1, 0);
  194.                 }
  195.                 rep(x,m) if (spot[x] > 0) G.add_edge(x+n, sink, spot[x], 0);
  196.  
  197.                 NF = G.maxflow(source, sink, n+m+2);
  198.  
  199.                 if (NF+1 == F)
  200.                 {
  201.                     assign[i] = job;
  202.                     printf("%d %d\n", i+1, job+1);
  203.                     F = NF;
  204.                     goto done;
  205.                 }
  206.                 spot[job]++;
  207.             }
  208.  
  209.             done:;
  210.         }
  211.  
  212.     }
  213.  
  214.     return 0;
  215. }
Add Comment
Please, Sign In to add comment