Submission #1268724

#TimeUsernameProblemLanguageResultExecution timeMemory
1268724rtriLove Polygon (BOI18_polygon)C++20
100 / 100
97 ms17852 KiB
#include <bits/stdc++.h>
using namespace std;

vector<int> points_to;
vector<set<int>> pointed_by;
vector<bool> solved;
vector<bool> useless;
int ans = 0;
int useless_count = 0;

void resolve_leaf(int u) {
  if (0 < pointed_by[u].size() || solved[u])
    return;
  if (solved[points_to[u]] && !useless[points_to[u]]) {
    useless_count++;
    solved[u] = 1;
    return;
  }

  int par = points_to[u];
  int gpar = points_to[par];
  pointed_by[gpar].erase(par);

  for (auto v : pointed_by[par])
    if (v != u && 0 == pointed_by[v].size()) {
      useless_count++;
      solved[v] = 1;
      useless[v] = 1;
    }

  points_to[points_to[u]] = u;
  pointed_by[u].insert(par);
  solved[u] = 1;
  solved[points_to[u]] = 1;
  ans++;

  if (useless[points_to[u]]) {
    useless_count--;
    useless[points_to[u]] = 0;
  }

  resolve_leaf(gpar);
}

void resolve_cycle(int u, int sx = -1) {
  if (solved[u])
    return;
  if (u == sx)
    return;
  if (sx == -1)
    sx = u;

  int par = points_to[u];
  int gpar = points_to[par];

  if (par == sx) {
    ans += 1;
    solved[u] = 1;
    return;
  }

  solved[u] = 1;
  solved[par] = 1;
  ans++;

  if (gpar != sx)
    resolve_cycle(gpar);
}

int main() {
  int n;
  cin >> n;

  points_to.resize(n, -1);
  pointed_by.resize(n);

  unordered_map<string, int> name_to_idx;
  solved.resize(n);
  useless.resize(n);
  for (int i = 0; i < n; i++) {
    string a, b;
    cin >> a >> b;

    if (!name_to_idx.count(a))
      name_to_idx[a] = name_to_idx.size();
    if (!name_to_idx.count(b))
      name_to_idx[b] = name_to_idx.size();

    int aidx = name_to_idx[a], bidx = name_to_idx[b];

    // cerr << "[" << a << "][" << b << "]" << endl;
    // cerr << aidx << " " << bidx << endl;

    points_to[aidx] = bidx;
    pointed_by[bidx].insert(aidx);

    if (aidx == bidx) {
      solved[aidx] = 1;
      useless[aidx] = 1;
      useless_count++;
    } else if (points_to[points_to[aidx]] == aidx) {
      solved[aidx] = 1;
      solved[bidx] = 1;
    }
  }

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

  for (int a = 0; a < n; a++)
    resolve_leaf(a);

  for (int a = 0; a < n; a++)
    if (points_to[a] != a && !solved[a])
      resolve_cycle(a);

  ans += useless_count;

  cout << ans << endl;

  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...