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;
typedef vector<int> vi;
void change_edge(int a, int b, int c, vi& graph, vector<vi>& rgraph) {
// a -> b --> a -> c
graph[a] = c;
rgraph[c].push_back(a);
rgraph[b].erase(find(rgraph[b].begin(), rgraph[b].end(), a));
}
void dfs(int v, int prev, vector<vi>& rgraph, vi& dp_nope, vi& dp_yup) {
dp_yup[v] = 0;
int nope_minus_yup = 0;
for (auto u : rgraph[v]) {
if (u == prev) continue; // important only for the first call
dfs(u, v, rgraph, dp_nope, dp_yup);
dp_yup[v] += dp_nope[u];
nope_minus_yup = max(nope_minus_yup, dp_nope[u] - dp_yup[u]);
}
dp_nope[v] = 1 + dp_yup[v] - nope_minus_yup;
}
int calc(int start, vi& graph, vector<vi>& rgraph, vi& dp_nope, vi& dp_yup) {
if (start == graph[start]) {
dfs(start, graph[start], rgraph, dp_nope, dp_yup);
return dp_nope[start];
}
dfs(graph[start], start, rgraph, dp_nope, dp_yup);
dfs(start, graph[start], rgraph, dp_nope, dp_yup);
return dp_yup[start] + dp_yup[graph[start]];
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
map<string,int> names;
int cur_name = 0;
vi graph(n);
vector<vi> rgraph(n);
int res = 0;
for (int i = 0; i < n; i++) {
string a, b;
cin >> a >> b;
if (names.find(a) == names.end()) names[a] = cur_name++;
if (names.find(b) == names.end()) names[b] = cur_name++;
int A = names[a], B = names[b];
graph[A] = B;
rgraph[B].push_back(A);
}
if (n & 1) { cout << -1 << '\n'; return 0; }
vi cycle_starters;
int cc_number = 1;
vi visited(n, 0);
for (int i = 0; i < n; i++) {
if (visited[i]) continue;
visited[i] = cc_number;
int j = graph[i];
while (visited[j] == 0) {
visited[j] = cc_number;
j = graph[j];
}
if (visited[j] == cc_number)
cycle_starters.push_back(j);
cc_number++;
}
vi dp_nope(n), // min number of arrows in subtree with root v if (v -> ) is changed
dp_yup(n); // min number of arrows in subtree with root v
for (auto u : cycle_starters) {
int cc_res = 1e9;
int v = graph[u],
w = graph[v],
x = graph[w];
if (u == v || u == w)
cc_res = calc(v, graph, rgraph, dp_nope, dp_yup);
else {
change_edge(w, x, v, graph, rgraph);
cc_res = min(cc_res, 1 + calc(v, graph, rgraph, dp_nope, dp_yup));
change_edge(w, v, x, graph, rgraph);
change_edge(v, w, u, graph, rgraph);
cc_res = min(cc_res, 1 + calc(v, graph, rgraph, dp_nope, dp_yup));
change_edge(v, u, w, graph, rgraph);
}
res += cc_res;
}
cout << res << '\n';
return 0;
}
# | 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... |