structNode { int color = -1; int to = 0; vector<int> neighbors; };
bitset<1001> visited;
boolfind(Node* graph, int node){ for (int i = 0; i < graph[node].neighbors.size(); i++) { if (!visited[graph[node].neighbors[i]]) { visited[graph[node].neighbors[i]] = 1; if (graph[graph[node].neighbors[i]].to == 0 || find(graph, graph[graph[node].neighbors[i]].to)) { graph[graph[node].neighbors[i]].to = node; returntrue; } } }
returnfalse; }
voidbigraph(Node* graph, int N){ int root = 1; do { graph[root].color = 0; queue<int> queue; queue.push(root); while (!queue.empty()) { int cur = queue.front(); queue.pop(); for (int i = 0; i < graph[cur].neighbors.size(); i++) { if (graph[graph[cur].neighbors[i]].color == -1) { graph[graph[cur].neighbors[i]].color = 1 - graph[cur].color; queue.push(graph[cur].neighbors[i]); } } }
root = 0; for (int i = 1; i <= N; i++) if (graph[i].color == -1) { root = i; break; } } while (root > 1); }
inthungarian(Node* graph, int N){ bigraph(graph, N); int minVertex = 0; for (int i = 1; i <= N; i++) { if (graph[i].color) { visited.reset(); minVertex += find(graph, i); } }
return minVertex; }
intmain(){ int N = 0, M = 0; cin >> N >> M; Node* graph = new Node[N + 1]; for (int i = 0; i < M; i++) { int a = 0, b = 0; cin >> a >> b; graph[a].neighbors.push_back(b); graph[b].neighbors.push_back(a); }
int minV = hungarian(graph, N); cout << minV << endl << N - minV << endl;