제출 #1298597

#제출 시각아이디문제언어결과실행 시간메모리
1298597tuongllLove Polygon (BOI18_polygon)C++20
46 / 100
124 ms14004 KiB
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 3;
const int inf32 = 1e9;

int n, to[N], in_deg[N];

namespace sub1 {
    int dp[1 << 20];
    void solve(){
        fill(dp + 1, dp + (1 << n), inf32);
        vector<int> gr;
        for (int mask = 1; mask < (1 << n); ++mask) if (__builtin_popcount(mask) % 2 == 0){
            gr.clear();
            for (int i = 0; i < n; ++i) if (mask >> i & 1)
                gr.push_back(i);

            for (int i = 0; i < (int)gr.size(); ++i){
                for (int j = i + 1; j < (int)gr.size(); ++j){
                    int u = gr[i], v = gr[j];
                    if (dp[mask ^ (1 << u) ^ (1 << v)] != inf32){
                        int c;
                        if (to[u] == v && to[v] == u) c = 0;
                        else if (to[u] == v || to[v] == u) c = 1;
                        else c = 2;

                        dp[mask] = min(dp[mask], dp[mask ^ (1 << u) ^ (1 << v)] + c);
                    }
                }
            }
        }

        cout << dp[(1 << n) - 1] << '\n';
    }
};

namespace sub2 {
    bool check(){
        for (int i = 0; i < n; ++i){
            if (in_deg[i] == 0) return false;
        }
        return true;
    }

    vector<bool> vis(N);

    void solve(){
        int res = 0;
        for (int i = 0; i < n; ++i) if (!vis[i]){
            int sz = 1;
            vis[i] = true;
            for (int u = to[i]; u != i; u = to[u]){
                ++sz;
                vis[u] = true;
            }

            if (sz > 2) res += sz / 2;
            if (sz & 1) ++res;
        }
        cout << res << '\n';
    }
};

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n;
    if (n & 1){
        cout << "-1\n";
        return 0;
    }

    vector<pair<string, string>> R;
    vector<string> people;
    for (int i = 0; i < n; ++i){
        string a, b;
        cin >> a >> b;
        R.emplace_back(a, b);
        people.push_back(a), people.push_back(b);
    }

    sort(begin(people), end(people));
    people.erase(unique(begin(people), end(people)), end(people));

    for (auto [a, b] : R){
        int i = lower_bound(begin(people), end(people), a) - begin(people);
        int j = lower_bound(begin(people), end(people), b) - begin(people);
        to[i] = j;
        ++in_deg[j];
    }

    if (n <= 20){
        sub1::solve();
        return 0;
    }
    if (sub2::check()){
        sub2::solve();
        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...