Submission #441817

#TimeUsernameProblemLanguageResultExecution timeMemory
441817alan8585Keys (IOI21_keys)C++17
9 / 100
163 ms17260 KiB
#include <vector> #include <stack> #include <set> #include <map> #include <bitset> #include <queue> using namespace std; const int MAXN = 3000; int T, in[MAXN], low[MAXN], instack[MAXN], bs[MAXN]; vector<pair<int, int>> e[MAXN]; vector<pair<int, int>> re[MAXN]; stack<int> st; vector<vector<int>> SCC; vector<int> flags; void dfs(int a) { instack[a] = 1; st.push(a); in[a] = low[a] = ++T; for(pair<int, int> i : e[a]) { if(!in[i.first]) { dfs(i.first); low[a] = min(low[a], low[i.first]); } else if(instack[i.first]) { low[a] = min(low[a], in[i.first]); } } if(in[a] == low[a]) { int now = -1; SCC.push_back(vector<int>(0)); do { now = st.top(); bs[now] = (int)SCC.size() - 1; st.pop(); instack[now] = 0; SCC.back().push_back(now); } while(now != a); } } int C[MAXN]; int find(int a) { if(C[a] == a) return a; return C[a] = find(C[a]); } vector<set<int>> has_key; bitset<MAXN> death; void merge(int a, int b) { //merge a into b if(find(a) == find(b)) return; a = find(a); b = find(b); C[a] = b; death[a] = 1; if(SCC[a].size() > SCC[b].size()) { SCC[a].swap(SCC[b]); has_key[a].swap(has_key[b]); } for(int i : SCC[a]) SCC[b].push_back(i); for(int i : has_key[a]) has_key[b].insert(i); } std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) { std::vector<int> ans(r.size(), 0); int n = r.size(), m = u.size(); for(int i = 0; i < m; i++) { if(r[u[i]] == c[i]) e[u[i]].push_back(make_pair(v[i], c[i])); if(r[v[i]] == c[i]) e[v[i]].push_back(make_pair(u[i], c[i])); } for(int i = 0; i < n; i++) { if(!in[i]) { dfs(i); } } vector<int> d_in(SCC.size(), 0); has_key.resize(SCC.size()); for(int i = 0; i < (int)SCC.size(); i++) for(int j : SCC[i]) { has_key[i].insert(r[j]); for(pair<int, int> k : e[j]) if(bs[k.first] != i) { re[bs[k.first]].push_back(make_pair(i, k.second)); d_in[i]++; } } queue<int> q; for(int i = 0; i < (int)SCC.size(); i++) { C[i] = i; if(d_in[i] == 0) q.push(i); } // for(int i = 0; i < n; i++) printf("%d %d\n", i, bs[i]); while(!q.empty()) { int now = q.front(); q.pop(); for(int x = 0; x < (int)re[now].size(); x++) for(pair<int, int> i : re[now]) { if(has_key[find(now)].find(i.second) != has_key[find(now)].end()) merge(now, i.first);//, printf("%d %d\n", now, i.first); d_in[i.first]--; if(d_in[i.first] == 0) q.push(i.first); } } int nmin = MAXN; // for(int i = 0; i < n; i++) printf("%d %d\n", i, bs[i]); for(int i = 0; i < (int)SCC.size(); i++) { bool flag = 0; if(C[i] == i) { flag = 1; for(int j : SCC[i]) { // printf("%d\n", j); for(pair<int, int> k : e[j]) { // printf("%d %d %d\n", k.first, bs[k.first], i); if(find(bs[k.first]) != i) flag = 0; } } } flags.push_back(flag); if(flag) nmin = min(nmin, (int)SCC[i].size()); } for(int i = 0; i < (int)SCC.size(); i++) { if(flags[i] && (int)SCC[i].size() == nmin) { for(int j : SCC[i]) ans[j] = 1; } } return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...