제출 #1368407

#제출 시각아이디문제언어결과실행 시간메모리
1368407maya_sLove Polygon (BOI18_polygon)C++20
54 / 100
164 ms33088 KiB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll SIZE = 100100;
bool info[SIZE];

ll cnt_matching(ll node, ll p, ll cnt, bool ignore_cyc, vector<ll> &vis, vector<vector<ll>> &g, vector<bool> &matched){
    vis[node] = cnt;
    ll ans = 0;
    for(ll i: g[node]) if((!vis[i] || (ignore_cyc && vis[i] == 1)) && (ignore_cyc || !info[i]) && !matched[i]){
        ans += cnt_matching(i, node, cnt, ignore_cyc, vis, g, matched);
        if(!matched[i] && !matched[node]) matched[i] = matched[node] = 1, ans++;
    }
    return ans;
}

ll cnt_for_cyc(vector<ll> &cyc, vector<bool> &matched, ll &pairs){
    ll s = 0, n = cyc.size();
    for(ll i = 0; i < n; i++) if(matched[cyc[i]]) s = i;
    if(!matched[cyc[s]]) {
        if(n == 2) {pairs++; return 0;}
        return n/2;
    }
    ll cnt = 0, ans = 0;
    for(ll i = (s+1) % n; i != s; i = (i+1) % n){
        if(matched[cyc[i]]) ans += cnt/2, cnt = 0;
        else cnt++;
    }
    ans += cnt/2;
    return ans;
}

ll solve(ll n, vector<ll> &edge, vector<vector<ll>> &rg){
    if(n % 2) return -1;
    vector<vector<ll>> cycles;
    vector<ll> vis(n+1);
    ll cnt = 0;
    for(ll i = 1; i <= n; i++) if(!vis[i]){
        ll node = i; cnt++;
        vector<ll> v;
        while(!vis[node]) v.push_back(node), vis[node] = cnt, node = edge[node];
        if(vis[node] == cnt) {
            ll x = node;
            vector<ll> cyc;
            while(v.size() && v.back() != x) info[v.back()] = 1, cyc.push_back(v.back()), v.pop_back();
            info[node] = 1, cyc.push_back(node);
            cycles.push_back(cyc);
        }
    }
    vector<vector<ll>> rg_same_dir_cyc(n+1);
    for(ll i = 1; i <= n; i++) {
        if(info[i] && info[edge[i]]) rg_same_dir_cyc[i].push_back(edge[i]);
        else rg_same_dir_cyc[edge[i]].push_back(i);
    }
    vector<ll> cnt_matching_vis(n+1);
    vector<bool> matched(n+1);
    ll ans = 0, pairs = 0, at = 0;
    for(vector<ll> cyc: cycles){
        ll node = 0;
        for(ll idx = 0; idx < cyc.size(); idx++){
            ll i = cyc[idx];
            ans += cnt_matching(i, 0, 1, 0, cnt_matching_vis, rg, matched);
            if(matched[i]){
                at = idx; node = i; break;
            }
        }
        if(node){
            ans += cnt_matching(cyc[(at + 1) % cyc.size()], 0, cnt, 1, cnt_matching_vis, rg, matched);
        }
        else if(cyc.size() == 2) pairs++;
        else ans += cyc.size() / 2;
    }
    return ans + n - 2*(pairs + ans);
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    ll n, cnt = 0; cin >> n;
    vector<ll> edge(n+1);
    vector<vector<ll>> rg(n+1);
    map<string, ll> names;
    for(ll i = 0; i < n; i++){
        string s, t; cin >> s >> t;
        if(!names[s]) names[s] = ++cnt;
        if(!names[t]) names[t] = ++cnt;
        edge[names[s]] = names[t]; rg[names[t]].push_back(names[s]);
    }
    cout << solve(n, edge, rg);
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…