Submission #1235300

#TimeUsernameProblemLanguageResultExecution timeMemory
1235300simplemind_31Parachute rings (IOI12_rings)C++20
37 / 100
1694 ms153120 KiB
#include <bits/stdc++.h> using namespace std; int N,canticriti,asegu=-1,canticiclo,ideal,contaaa,deberia; vector<int> degree,dsu,may3,posibilidad,cantiposi,dsuuu,degreeeeee; vector<vector<int>> graph; set<pair<int,int>> unidos; vector<bool> pertenececiclo; int target=-1; bool dfs(int now,int ante){ if(pertenececiclo[now]){ return false; } if(now==target){ posibilidad[now]++; contaaa++; cantiposi[posibilidad[now]]++; return pertenececiclo[now]=true; } for(auto u:graph[now]){ if(u==ante){ continue; } if(dfs(u,now)){ posibilidad[now]++; contaaa++; cantiposi[posibilidad[now]]++; return pertenececiclo[now]=true; } } return false; } int find(int x){return dsu[x]==x?x:dsu[x]=find(dsu[x]);} bool unite(int x,int y){ if((x=find(x))==(y=find(y))){ return false; } dsu[x]=y; return true; } int find2(int x){return dsuuu[x]==x?x:dsuuu[x]=find2(dsuuu[x]);} bool unite2(int x,int y){ if((x=find2(x))==(y=find2(y))){ return false; } dsuuu[x]=y; return true; } void Init(int N_){ deberia=0; cantiposi.clear(); posibilidad.clear(); graph.clear(); degree.clear(); dsu.clear(); pertenececiclo.clear(); may3.clear(); canticiclo=ideal=contaaa=0; graph.resize(canticriti=N=N_); degree.resize(N); dsu.resize(N); cantiposi.resize(N); posibilidad.resize(N); pertenececiclo.assign(N,false); cantiposi[0]=N; for(int i=0;i<N;i++){ dsu[i]=i; } } void reinicar(){ Init(N); for(auto u:unidos){ if(u.first==asegu || u.second==asegu){ continue; } degree[u.first]++; degree[u.second]++; graph[u.first].push_back(u.second); graph[u.second].push_back(u.first); if(degree[u.first]>2 || degree[u.second]>2 || !unite(u.first,u.second)){ canticriti=0; return; } } canticriti=1; } void Link(int A,int B){ if(canticriti==0){ return; } //nuevo variante=ciclos // si existe 2 ciclos entonces canti=0 // si existe 1 ciclo critic ring debe estar dentro del ciclo if(asegu!=-1){ // al encontrar asegu inicio de nuevo pero olvidandome del asegu, es decir nunca unir asegu if(asegu!=A && asegu!=B){ degree[A]++; degree[B]++; graph[A].push_back(B); graph[B].push_back(A); //si encuentro ciclo entonces canti=0; if(degree[A]>2 || degree[B]>2 || !unite(A,B)){ canticriti=0; return; } } }else{ unidos.insert({min(A,B),max(A,B)}); if(!unite(A,B)){ target=B; ideal++; if(dfs(A,B)){ deberia++; canticiclo++; if(canticiclo>1){ canticriti=0; return; } } } degree[A]++; degree[B]++; graph[A].push_back(B); graph[B].push_back(A); if(degree[A]>=4){ deberia++; posibilidad[A]++; cantiposi[posibilidad[A]]++; } if(degree[B]>=4){ deberia++; posibilidad[B]++; cantiposi[posibilidad[B]]++; } if(degree[A]==3){ deberia++; may3.push_back(A); for(auto u:graph[A]){ posibilidad[u]++; cantiposi[posibilidad[u]]++; } posibilidad[A]++; cantiposi[posibilidad[A]]++; } if(degree[B]==3){ deberia++; may3.push_back(B); for(auto u:graph[B]){ posibilidad[u]++; cantiposi[posibilidad[u]]++; } posibilidad[B]++; cantiposi[posibilidad[B]]++; } if(cantiposi[deberia]==0){ canticriti=0; return; }else if(cantiposi[deberia]==1){ for(int i=0;i<N;i++){ if(posibilidad[i]==deberia){ asegu=i; reinicar(); return; } } }else if(may3.size()==2){ if(ideal>1){ //check brute force for(int i=0;i<N;i++){ if(posibilidad[i]==deberia){ dsuuu.clear(); degreeeeee.clear(); dsuuu.resize(N); degreeeeee.resize(N); for(int i=0;i<N;i++){ dsuuu[i]=i; } for(auto u:unidos){ if(u.first==i || u.second==i){ continue; } degreeeeee[u.first]++; degreeeeee[u.second]++; if(!unite2(u.first,u.second) || degreeeeee[u.first]>2 || degreeeeee[u.second]>2){ cantiposi[deberia]--; posibilidad[i]--; break; } } } } canticriti=cantiposi[deberia]; return; }else{ canticriti=cantiposi[deberia]; return; } }else if(may3.size()==1){ canticriti=cantiposi[deberia]; return; }else{ canticriti=cantiposi[deberia]; return; } } } int CountCritical(){return canticriti;}
#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...