This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct unionfind{
    vector<int> chef;
    vector<int> cnt;
    unionfind(int n){
        chef.resize(n);
        iota(chef.begin(), chef.end(), 0);
        cnt.resize(n, 1);
    }
    int find(int a){
        if(chef[a]==a) return a;
        return chef[a]=find(chef[a]);
    }
    void unite(int a, int b){
        if(find(a)==find(b)) return;
        cnt[find(b)]+=cnt[find(a)];
        chef[find(a)]=find(b);
    }
};
void dfs(int v, vector<vector<int> >& adi, vector<bool>& vis, unionfind& ufind, vector<int>& postorder, bool first){
    assert(!vis[v]);
    vis[v]=true;
    for(auto u: adi[v]){
        if(!vis[u]){
            dfs(u, adi, vis, ufind, postorder, first);
            if(!first){
                ufind.unite(u, v);
            }
        }
    }
    if(first){
        postorder.push_back(v);
    }
}
void kosaraju(int n, vector<vector<int> >& adi, vector<vector<int> >& rev, unionfind& ufind){
    vector<int> postorder;
    vector<bool> vis(n);
    for(int v=0; v<n; v++){
        if(!vis[v]) {
            dfs(v, adi, vis, ufind, postorder, true);
        }
    }
    vis.assign(n, false);
    for(int v=n-1; v>=0; v--){
        if(!vis[postorder[v]]) {
            dfs(postorder[v], rev, vis, ufind, postorder, false);
        }
    }
}
void dfs_dp(int v, vector<vector<int> >& adi, vector<vector<int> >& dp, vector<bool>& vis, unionfind& ufind){
    if(vis[v]) return;
    vis[v]=true;
    int add=0;
    if(ufind.cnt[v]!=2){
        add=(ufind.cnt[v]+1)/2;
    }
    int sum0=0;
    for(auto u: adi[v]){
        dfs_dp(u, adi, dp, vis, ufind);
        sum0+=dp[u][0];
    }
    dp[v][1]=sum0;
    dp[v][0]=sum0+add;
    for(auto u: adi[v]){
        if(ufind.cnt[v]%2==1){
            dp[v][0]=min(dp[v][0], sum0-dp[u][0]+dp[u][1]+add);
        }
    }
    //cout << v << " " << ufind.find(v) << " " << ufind.cnt[ufind.find(v)] << "\n";
    //cout << dp[v][0] << " " << dp[v][1] << "\n";
}
int solve(int n, vector<vector<int> >& adi_alt, vector<vector<int> >& rev, vector<int>& par){
    unionfind ufind(n);
    kosaraju(n, adi_alt, rev, ufind);
    vector<vector<int> > adi(n);
    for(int u=0; u<n; u++){
        int v=par[u];
        if(v==-1) continue;
        if(ufind.find(u)!=ufind.find(v)){
            adi[ufind.find(v)].push_back(ufind.find(u));
        }
    }
    /*for(int i=0; i<n; i++){
        cout << i << ": " << ufind.find(i) << "\n";
    }
    for(int i=0; i<n; i++){
        if(ufind.find(i)==i){
            cout << i << ": ";
            for(auto e: adi[i]){
                cout << e << " ";
            }
            cout << "\n";
        }
    }*/
    vector<bool> vis(n);
    vector<vector<int> > dp(n, vector<int> (2));
    int ans=0;
    for(int v=0; v<n; v++){
        if(vis[ufind.find(v)]) continue;
        if(ufind.find(v)!=v || par[v]==-1){
            dfs_dp(ufind.find(v), adi, dp, vis, ufind);
            ans+=dp[ufind.find(v)][0];
        }
    }
    return ans;
}
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    int cnt=1;
    map<string, int> ind;
    vector<vector<int> > adi(n);
    vector<vector<int> > rev(n);
    vector<int> par(n, -1);
    for(int i=0; i<n; i++){
        string s, t;
        cin >> s >> t;
        if(ind[s]==0){
            ind[s]=cnt;
            cnt++;
        }
        if(ind[t]==0){
            ind[t]=cnt;
            cnt++;
        }
        int a=ind[s];
        int b=ind[t];
        if(a!=b){
            adi[b-1].push_back(a-1);
            rev[a-1].push_back(b-1);
            par[a-1]=b-1;
        }
    }
    if(n%2==1){
        cout << -1 << "\n";
        return 0;
    }
    cout << solve(n, adi, rev, par) << "\n";
}
| # | 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... |