Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- int n, m, k, ct;
- bool br[35][35];
- int st, fin;
- bool viss[35];
- vector <int> spec[12];
- int vis[500], timer = 0, level[500], ptr[500];
- queue <int> q;
- struct dat { int from, to, capa, flow; };
- vector <dat> E;
- vector <int> a[500];
- void addedge(int u, int v, int wei)
- {
- E.push_back({u, v, wei, 0});
- E.push_back({v, u, 0, 0});
- int x1 = E.size() - 2, x2 = E.size() - 1;
- a[u].push_back(x1);
- a[v].push_back(x2);
- }
- void Edge(int mid)
- {
- for (int i = 1; i <= m; ++i)
- {
- addedge(0, i, mid);
- }
- for (int i = 1; i <= m; ++i)
- {
- memset(viss, 0, sizeof(viss));
- for (int j = 0; j < spec[i].size(); ++j)
- {
- for (int t = j + 1; t < spec[i].size(); ++t)
- {
- int u = spec[i][j], v = spec[i][t];
- if (!br[u][v]) continue;
- ct++;
- addedge(i, ct + m + n, 1);
- addedge(ct + m + n, m + u, 1);
- addedge(ct + m + n, m + v, 1);
- viss[u] = viss[v] = true;
- }
- }
- for (int u : spec[i])
- {
- if (viss[u]) continue;
- addedge(i, m + u, 1);
- }
- }
- fin = m + n + ct + 1;
- for (int i = 1; i <= n; ++i)
- {
- addedge(m + i, fin, 1);
- }
- }
- bool bfs()
- {
- level[st] = 0; vis[st] = ++timer; q.push(st);
- for (int i = 0; i <= fin; ++i) ptr[i] = 0;
- while (!q.empty())
- {
- int u = q.front(); q.pop();
- for (int id : a[u])
- {
- int v = E[id].to;
- if (E[id].capa - E[id].flow < 1 || vis[v] == timer) continue;
- level[v] = level[u] + 1;
- vis[v] = timer;
- q.push(v);
- }
- }
- return vis[fin] == timer;
- }
- int dfs(int u, int pushed)
- {
- if (pushed == 0) return 0;
- if (u == fin) return pushed;
- for (int &cid = ptr[u]; cid < (int)a[u].size(); ++cid)
- {
- int id = a[u][cid];
- int v = E[id].to;
- if (level[u] + 1 != level[v] || E[id].capa - E[id].flow < 1) continue;
- int tr = dfs(v, min(pushed, E[id].capa - E[id].flow));
- if (tr == 0) continue;
- E[id].flow += tr;
- E[id ^ 1].flow -= tr;
- return tr;
- }
- return 0;
- }
- bool Check(int mid)
- {
- E.clear();
- ct = 0;
- for (int i = 0; i < 500; ++i)
- {
- level[i] = 0;
- vis[i] = 0;
- if (a[i].empty()) break;
- a[i].clear();
- }
- timer = 0;
- Edge(mid);
- int f = 0;
- while (bfs())
- {
- while (int pushed = dfs(st, 2e9)) { f += pushed; }
- }
- return (f == n);
- }
- void solve()
- {
- int l = (n + m - 1) / m, r = m, ans = -1;
- while (l <= r)
- {
- int mid = (l + r) / 2;
- if (Check(mid))
- {
- r = mid - 1;
- ans = mid;
- }
- else l = mid + 1;
- }
- cout << ans;
- }
- int main()
- {
- ios::sync_with_stdio(0);
- cin.tie(0);
- if (fopen("input.txt", "r"))
- assert(freopen("input.txt", "r", stdin));
- cin >> m >> n;
- for (int i = 1; i <= m; ++i)
- {
- int x; cin >> x;
- while (x--)
- {
- int u; cin >> u;
- spec[i].push_back(u);
- }
- }
- cin >> k;
- for (int i = 1; i <= k; ++i)
- {
- int u, v;
- cin >> u >> v;
- br[u][v] = br[v][u] = 1;
- }
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement