Submission #371528

#TimeUsernameProblemLanguageResultExecution timeMemory
371528mihai145Love Polygon (BOI18_polygon)C++14
100 / 100
261 ms31760 KiB
// // Created by mihai145 on 26.02.2021. // #include <iostream> #include <vector> #include <unordered_map> #include <stack> #include <algorithm> using namespace std; const int NMAX = 1e5; int N, k; unordered_map<string, int> names; vector<int> g[NMAX + 5]; vector<int> bi[NMAX + 5]; bool solvedFor[NMAX + 5]; int Get(string s) { if (!names[s]) { names[s] = ++k; } return names[s]; } void dfsConex(int node) { solvedFor[node] = true; for (int son : bi[node]) { if (!solvedFor[son]) { dfsConex(son); } } } vector<int> cycle; bool inStack[NMAX + 5], cycleNode[NMAX + 5]; stack<int> st; void dfsFindCycle(int node) { inStack[node] = true; st.push(node); for (int son : g[node]) { if (inStack[son] == true) { while (!st.empty() && st.top() != son) { cycle.push_back(st.top()); cycleNode[st.top()] = true; st.pop(); } cycle.push_back(st.top()); cycleNode[st.top()] = true; return; } else { dfsFindCycle(son); } } } int dpTree[NMAX + 5][2], dpCycle[NMAX + 2][2]; void CalcDpTree(int node, int par = -1) { int nrSons = 0; for (int son : bi[node]) { if (son != par && !cycleNode[son]) { nrSons++; CalcDpTree(son, node); } } if (nrSons == 0) { dpTree[node][0] = dpTree[node][1] = 0; } else { int maxMatch = -N - 1; for (int son : bi[node]) { if (son != par && !cycleNode[son]) { dpTree[node][0] += max(dpTree[son][0], dpTree[son][1]); dpTree[node][1] += max(dpTree[son][0], dpTree[son][1]); maxMatch = max(maxMatch, -max(dpTree[son][0], dpTree[son][1]) + dpTree[son][0]); } } dpTree[node][1] += maxMatch; dpTree[node][1] += 1; } } int keeps; void solve(int node) { dfsConex(node); while (!st.empty()) { st.pop(); } cycle.clear(); dfsFindCycle(node); // cout << "New cycle:\n"; // for(auto it : cycle) { // cout << it << ' '; // } // // cout << '\n' << '\n'; for (int vert : cycle) { CalcDpTree(vert); } if ((int) cycle.size() == 1) { keeps += max(dpTree[cycle[0]][0], dpTree[cycle[0]][1]); return; } reverse(cycle.begin(), cycle.end()); int maxKeeps = 0; ///we do not match the first node in the cycle with the last one dpCycle[cycle[0]][0] = dpTree[cycle[0]][0]; dpCycle[cycle[0]][1] = dpTree[cycle[0]][1]; for (int i = 1; i < (int) cycle.size(); i++) { int maxPrev = max(dpCycle[cycle[i - 1]][0], dpCycle[cycle[i - 1]][1]); dpCycle[cycle[i]][0] = maxPrev + dpTree[cycle[i]][0]; dpCycle[cycle[i]][1] = max(maxPrev + dpTree[cycle[i]][1], dpCycle[cycle[i - 1]][0] + 1 + dpTree[cycle[i]][0]); } maxKeeps = max(dpCycle[cycle.back()][0], dpCycle[cycle.back()][1]); ///we match the first node in the cycle with the last one dpCycle[cycle[0]][0] = dpTree[cycle[0]][0]; dpCycle[cycle[0]][1] = 0; for (int i = 1; i < (int) cycle.size(); i++) { int maxPrev = max(dpCycle[cycle[i - 1]][0], dpCycle[cycle[i - 1]][1]); dpCycle[cycle[i]][0] = maxPrev + dpTree[cycle[i]][0]; if (i > 1) { dpCycle[cycle[i]][1] = max(maxPrev + dpTree[cycle[i]][1], dpCycle[cycle[i - 1]][0] + 1 + dpTree[cycle[i]][0]); } else { dpCycle[cycle[i]][1] = maxPrev + dpTree[cycle[i]][1]; } } maxKeeps = max(maxKeeps, dpCycle[cycle.back()][1]); maxKeeps = max(maxKeeps, dpCycle[cycle.back()][0] + 1); if ((int) cycle.size() == 2) { maxKeeps = max(maxKeeps, 2 + dpTree[cycle[0]][0] + dpTree[cycle[1]][0]); } keeps += maxKeeps; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> N; if (N % 2 == 1) { cout << -1 << '\n'; return 0; } for (int i = 1; i <= N; i++) { string s, t; cin >> s >> t; g[Get(s)].push_back(Get(t)); bi[Get(s)].push_back(Get(t)); bi[Get(t)].push_back(Get(s)); } for (int i = 1; i <= N; i++) { if (!solvedFor[i]) { solve(i); } } cout << N - keeps << '\n'; 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...