# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1259599 | SzymonKrzywda | Worm Worries (BOI18_worm) | C++20 | 0 ms | 0 KiB |
#include <iostream>
#include <set>
#include <unordered_set>
#include <vector>
#include <map>
using namespace std;
using pii = pair<int, int>;
using vi = vector<int>;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
string s1, s2;
int n;
cin >> n;
unordered_map<string, int> mapka;
vector<int> graf(2 * n);
vector<vi> graf2(2 * n);
for (int i = 0; i < n; i++) {
cin >> s1 >> s2;
if (mapka.find(s1) == mapka.end()) mapka[s1] = mapka.size();
if (mapka.find(s2) == mapka.end()) mapka[s2] = mapka.size();
graf[mapka[s1]] = mapka[s2];
graf2[mapka[s2]].push_back(mapka[s1]);
}
n = mapka.size();
if (n % 2 == 1) {
cout << -1 << '\n';
return 0;
}
vector<int> indegree(n, 0);
vector<int> stos;
vector<vector<int>> dp(n, vector<int>(2, 0));
vector<int> rozmiar(n, 0);
for (int i = 0; i < n; i++) {
indegree[i] = graf2[i].size();
if (indegree[i] == 0) stos.push_back(i);
}
while (stos.size()) {
int v = stos.back();
stos.pop_back();
rozmiar[v] = 1;
for (int s : graf2[v]) {
rozmiar[v] += rozmiar[s];
dp[v][0] += max(dp[s][0], dp[s][1]);
}
for (int s : graf2[v]) {
dp[v][1] = max(dp[v][1], dp[v][0] - max(dp[s][1], dp[s][0]) + dp[s][0] + 1);
}
indegree[graf[v]] --;
if (indegree[graf[v]] == 0) stos.push_back(graf[v]);
}
vector<bool> polaczony(n, 0);
vector<int> pop_cykl(n, 0);
int wynik = 0;
for (int i = 0; i < n; i++) {
if (indegree[i] == 0) continue;
int suma_poddrzew = 0, suma_wynik = 0;
for (int s : graf2[i]) {
if (indegree[s] != 0) continue;
if (dp[s][0] == dp[s][1]) {
polaczony[i] = 1;
}
suma_poddrzew += rozmiar[s];
suma_wynik += max(dp[s][0], dp[s][1]);
}
pop_cykl[graf[i]] = i;
//cout << i << ' ' << suma_poddrzew << ' ' << suma_wynik << ' ' << polaczony[i] << '\n';
wynik += suma_poddrzew - suma_wynik - polaczony[i];
}
for (int i = 0; i < n; i++) {
if (indegree[i] == 0 || polaczony[i]) continue;
if (!polaczony[graf[i]]) {
polaczony[graf[i]] = 1;
polaczony[i] = 1;
}
else if (!polaczony[pop_cykl[i]]) {
polaczony[pop_cykl[i]] = 1;
polaczony[i] = 1;
}
wynik += 2 - polaczony[i];
}
cout << wynik << '\n';
return 0;
}