Submission #1330741

#TimeUsernameProblemLanguageResultExecution timeMemory
1330741miminyteLove Polygon (BOI18_polygon)C++20
29 / 100
510 ms24336 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>

using namespace std;

int main() {
    int n, cnt = 0;
    vector <pair<string, string>> input;
    map<string, int> mp;
    vector<string> names;
    vector <int> v;
    string s1, s2;

    cin >> n;

    if (n % 2) {
        cout << -1;
        return 0;
    }

    for (int i = 0; i < n; i++) {
        cin >> s1 >> s2;
        input.push_back({s1, s2});
    }

    for (int i = 0; i < n; i++) {
        mp[input[i].first] = cnt;
        names.push_back(input[i].first);
        cnt++;
    }

    v.resize(n);

    for (int i = 0; i < n; i++) {
        v[mp[input[i].first]] = mp[input[i].second];
    }

    int remaining = n;

    // Check for pairs
    for (int i = 0; i < n; i++) {
        if (v[i] != -1 && i != v[i] && i == v[v[i]]) {
            remaining -= 2;
            v[i] = -1; // Mark as paired
            v[v[i]] = -1; // Mark the pair as well

            cerr << "Paired: " << names[i] << " and " << names[v[i]] << endl;
        }
    }

    cerr << "Finished default pairing. Remaining: " << remaining << endl;

    vector<int> indegree(n, 0); // Out-degree is 1 for all nodes

    for(int i = 0; i < n; i++) {
        if(v[i] != -1) {
            indegree[v[i]]++;
        }
    }

    set<int> candidates;

    for (int i = 0; i < n; i++) {
        if(v[i] != -1 && indegree[i] == 0) {
            candidates.insert(i);
        }
    }

    cerr << "Initial candidates with in-degree 0: " << candidates.size() << endl;

    int moves = 0;

    // Go through candidates (with in-degree 0)
    while(!candidates.empty()) {
        int current = *candidates.begin();
        candidates.erase(candidates.begin());
        
        if(v[current] != -1 && v[v[current]] != -1) {
            cerr << "Pairing: " << names[current] << " and " << names[v[current]] << ". The edges are " << names[current] << " -> " << names[v[current]] << " -> " << names[v[v[current]]] << endl;

            moves++;
            remaining -= 2;

            indegree[v[v[current]]]--;
            if(indegree[v[v[current]]] == 0) {
                candidates.insert(v[v[current]]);
            }

            v[v[current]] = -1; // Mark the pair as removed
            v[current] = -1; // Mark as removed
        } 
            
    }

    cerr << "Finished processing candidates. Moves: " << moves << ", Remaining: " << remaining << endl;

    cout << moves + remaining;

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...