#ifndef FOAM_H
#define FOAM_H
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <cassert>
#include <map>
#include <fstream>
#include <unordered_set>
#include <unordered_map>
#include <list>
#include <climits>
#include <cstdlib>
#include <numeric>
#endif
class dp {
private:
    int n{};
    std::vector<std::vector<int>> cac{};
    std::vector<std::vector<int>> adj{};
    std::vector<bool> visited{};
    int solve(int i, int j, int p) {
        visited[i] = 1;
        if (cac[i][j] != -1) {
            return cac[i][j];
        }
        std::vector<std::vector<int>> neigh(adj[i].size(), std::vector<int>(2, 0));
        int total{ 0 };
        
        for (int k{ 0 }; k < adj[i].size(); ++k) {
            if (adj[i][k] == p) {
                continue;
            }
            neigh[k][0] = solve(adj[i][k], 0, i);
            neigh[k][1] = solve(adj[i][k], 1, i) + 1;
            total += neigh[k][0];
        }
        int best{ total };
        if (j == 0) {
            for (int k{ 0 }; k < adj[i].size(); ++k) {
                if (adj[i][k] == p) {
                    continue;
                }
                best = std::max(best, total - neigh[k][0] + neigh[k][1]);
            }
        }
        return cac[i][j] = best;
        
    }
public:
    dp(int N, std::vector<std::vector<int>> ADJ) : n{ N }, adj{ ADJ } {
        cac.assign(N, std::vector<int>(2, -1));
        visited.resize(n, 0);
    }
    std::vector<int> get() {
        std::vector<int> out{};
        for (int i{ 0 }; i < n; ++i) {
            if (!visited[i]) {
                out.push_back(solve(i, 0, i));
            }
        }
        return out;
    }
};
void dfs(int i, std::vector<int>& link, std::vector<int>& visited, int v, std::vector<int>& loop) {
    if (visited[i] != -1) {
        return;
    }
    visited[i] = v;
    if (visited[link[i]] == v) {
        loop[v] = i;
    }
    dfs(link[i], link, visited, v, loop);
    visited[i] = visited[link[i]];
}
int main() {
    int n{};
    std::cin >> n;
    if (n & 1) {
        std::cout << -1;
        return 0;
    }
    std::map<std::string, int> b;
    std::vector<int> link(n);
    
    int id{ 0 };
    for (int i{ 0 }; i < n; ++i) {
        std::string x{}, y{};
        std::cin >> x >> y;
        if (!b.count(x)) {
            b[x] = id++;
        }
        if (!b.count(y)) {
            b[y] = id++;
        }
        link[b[x]] = b[y];
    }
    std::vector<int> visited(n, -1);
    std::vector<int> loop(n, -1);
    for (int i{ 0 }; i < n; ++i) {
        dfs(i, link, visited, i, loop);
    }
    std::vector<std::vector<int>> clumps(n);
    for (int i{ 0 }; i < n; ++i) {
        clumps[visited[i]].push_back(i);
    }
    std::vector<std::vector<int>> option1(n), option2(n);
    int twocycles{ 0 };
    for (int i{ 0 }; i < n; ++i) {
        bool twocycleflag{ 0 };
        if (clumps[i].empty()) {
            continue;
        }
        if (link[link[loop[i]]] == loop[i] && link[loop[i]] != loop[i]) {
            twocycles++;
            twocycleflag = 1;
        }
        
        for (auto k : clumps[i]) {
            if (link[k] == k) {
                continue;
            }
            if (twocycleflag) {
                if (link[k] == loop[i] || link[k] == link[loop[i]]) {
                    continue;
                }
            }
            if (k != loop[i]) {
                option1[k].push_back(link[k]);
                option1[link[k]].push_back(k);
            }
            if (k != link[loop[i]]) {
                option2[k].push_back(link[k]);
                option2[link[k]].push_back(k);
            }
            
        }
    }
    dp solver1(n, option1), solver2(n, option2);
    int total{ twocycles * 2 };
    std::vector<int> x{ solver1.get() }, y{ solver2.get() };
    for (int i{ 0 }; i < x.size(); ++i) {
        total += std::max(x[i], y[i]);
    }
    std::cout << n - total;
    
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |