Submission #1013453

#TimeUsernameProblemLanguageResultExecution timeMemory
1013453LudisseyParachute rings (IOI12_rings)C++14
0 / 100
1000 ms155424 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define sz(a) (int)a.size() #define all(a) a.begin(), a.end() int n; bool hasloop=false; vector<vector<int>> neigh; vector<int> visited; vector<int> parent; vector<int> pr; vector<int> sz; vector<int> crit; vector<int> incycle; vector<int> iscycle; vector<int> orig; int timer=0; int exceptation=-1; bool cycl=0; int cc=0; int c=0; int upds=0; int getParent(int a) { if(parent[a]==a) return a; else return parent[a]=getParent(parent[a]); } void unite(int a, int b){ a=getParent(a); b=getParent(b); if(a==b) return; if(sz[b]>sz[a]) swap(a,b); sz[a]+=sz[b]; parent[a]=b; } void detect_cycle(int x, int p) { if(visited[x]==2) return; if (visited[x] == 1) { vector<int> v; iscycle[x]=true; incycle.push_back(x); int cr=pr[x]; while (cr!=x) { incycle.push_back(cr); iscycle[cr]=true; cr=pr[cr]; } return; } pr[x]=p; visited[x]=1; for (int to : neigh[x]) { if (to==p) continue; detect_cycle(to,x); } visited[x]=2; } void get_origin(int x, int p,int og) { if(orig[x]>=0) return; orig[x]=og; for (int to : neigh[x]) { if (to==p||iscycle[to]) continue; get_origin(to,x,orig[x]); } } void Init(signed N_) { n = N_; parent.resize(n); visited.resize(n,0); neigh.resize(n); orig.resize(n,-1); cc=0; c=n; sz.resize(n,1); iscycle.resize(n,0); pr.resize(n,-1); crit.resize(n,0); upds=0; for (int i = 0; i < n; i++) parent[i]=i; } void update_crit(int X){ if(sz(neigh[X])==3){ crit[neigh[X][0]]++; crit[neigh[X][1]]++; crit[neigh[X][2]]++; crit[X]++; upds++; c=0; if(crit[neigh[X][0]]==upds) c++; if(crit[neigh[X][1]]==upds) c++; if(crit[neigh[X][2]]==upds) c++; if(crit[X]==upds) c++; }else if(sz(neigh[X])>3){ crit[X]++; upds++; c=0; if(crit[X]==upds) c++; } } void case1(int A, int B){ //two vertex of different sets O(1); unite(A,B); if(orig[A]>=0&&orig[B]<0) get_origin(B,A,orig[A]); else if(orig[B]>=0&&orig[A]<0) get_origin(A,B,orig[B]); update_crit(A); update_crit(B); } void case2(int A, int B){ //two vertex of same sets !! NO CYCLE !! O(N+M) detect_cycle(A,B); cycl=1; upds++; c=0; for (int i = 0; i < sz(incycle); i++){ crit[incycle[i]]++; if(crit[incycle[i]]==upds) c++; } visited.clear(); visited.resize(n,0); for (int i = 0; i < sz(incycle); i++) get_origin(incycle[i],-1,incycle[i]); case1(A,B); } //UPD void case3(int A, int B){ //two vertex of same sets !! CYCLE !! O(1) //cerr << "case 3"; if(orig[A]<0||orig[B]<0) { upds++; return; } upds++; c=0; crit[orig[A]]++; if(crit[orig[A]]==upds) c++; if(orig[A]!=orig[B]) { crit[orig[B]]++; if(crit[orig[B]]==upds) c++; } update_crit(A); update_crit(B); update_crit(orig[A]); update_crit(orig[B]); } void Link(signed A, signed B) { neigh[A].push_back(B); neigh[B].push_back(A); if(getParent(A)==getParent(B)){ if(cycl) case3(A,B); else case2(A,B); }else{ case1(A,B); } } signed CountCritical() { return c; }
#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...