#include <cstdio> #include <cstring> #include <climits> #include <new> #include <queue> #include <algorithm> const int MAXN = 400; const int MAXM = 6000; struct Node; struct Edge; struct Node { Edge *e, *c; int level, id; bool vis; } N[MAXN + 5]; struct Edge { Node *fr, *to; Edge *ne, *rev; int cap, flow; Edge() {} Edge(Node *fr, Node *to, int cap) : fr(fr), to(to), ne(fr->e), cap(cap), flow(0) {} }; inline void addEdge(int fr, int to, int cap) { N[fr].e = new Edge(&N[fr], &N[to], cap); N[to].e = new Edge(&N[to], &N[fr], 0); N[fr].e->rev = N[to].e, N[to].e->rev = N[fr].e; } struct Dinic { bool makeLevelGraph(Node *s, Node *t, int n) { for (int i = 0; i < n; i++) N[i].c = N[i].e, N[i].level = 0; std::queue<Node *> q; q.push(s); s->level = 1; while (!q.empty()) { Node *v = q.front(); q.pop(); for (Edge *e = v->e; e; e = e->ne) { if (e->cap > e->flow && !e->to->level) { e->to->level = v->level + 1; if (e->to == t) return true; q.push(e->to); } } } return false; } int findPath(Node *s, Node *t, int limit = INT_MAX) { if (s == t) return limit; for (Edge *&e = s->c; e; e = e->ne) { if (e->cap > e->flow && e->to->level == s->level + 1) { int flow = findPath(e->to, t, std::min(e->cap - e->flow, limit)); if (flow > 0) { e->flow += flow; e->rev->flow -= flow; return flow; } } } return 0; } int operator()(int s, int t, int n) { int res = 0; while (makeLevelGraph(&N[s], &N[t], n)) { int flow; if ((flow = findPath(&N[s], &N[t])) > 0) res += flow; } return res; } } dinic; void printPath(Node *v) { printf("%d ", v->id); v->vis = true; for (Edge *e = v->e; e; e = e->ne) { if (e->flow == e->cap && e->to->id != 0 && !N[e->to->id].vis) { printPath(&N[e->to->id]); break; } } } int main() { int n, m; scanf("%d %d", &n, &m); const int s = 0, t = n * 2 + 1; for (int i = 1; i <= n; i++) addEdge(s, i, 1), addEdge(i + n, t, 1), N[i].id = N[i + n].id = i; for (int i = 1; i <= m; i++) { int u, v; scanf("%d %d", &u, &v); addEdge(u, v + n, 1); } int res = dinic(s, t, n * 2 + 2); for (int i = 1; i <= n; i++) { if (!N[i].vis) { printPath(&N[i]); puts(""); } } printf("%d\n", n - res); return 0; }
|