#include <bits/stdc++.h>
using namespace std;
int N,canticriti,asegu=-1,canticiclo,ideal,contaaa,maxiposi;
vector<int> degree,dsu,may3,posibilidad,cantiposi;
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]++;
cantiposi[posibilidad[now]]++;
maxiposi=max(maxiposi,posibilidad[now]);
return pertenececiclo[now]=true;
}
for(auto u:graph[now]){
if(u==ante){
continue;
}
if(dfs(u,now)){
posibilidad[now]++;
cantiposi[posibilidad[now]]++;
maxiposi=max(maxiposi,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;
}
void Init(int N_){
maxiposi=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);
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)){
canticiclo++;
if(canticiclo>1){
canticriti=0;
return;
}
}
}
degree[A]++;
degree[B]++;
graph[A].push_back(B);
graph[B].push_back(A);
if(degree[A]>3 && degree[B]>3){
canticriti=0;
}else if(degree[A]>3){
asegu=A;
reinicar();
}else if(degree[B]>3){
asegu=B;
reinicar();
}else{
if(degree[A]==3){
may3.push_back(A);
for(auto u:graph[A]){
posibilidad[u]++;
cantiposi[posibilidad[u]]++;
maxiposi=max(maxiposi,posibilidad[u]);
}
posibilidad[A]++;
cantiposi[posibilidad[A]]++;
maxiposi=max(maxiposi,posibilidad[A]);
}
if(degree[B]==3){
may3.push_back(B);
for(auto u:graph[B]){
posibilidad[u]++;
cantiposi[posibilidad[u]]++;
maxiposi=max(maxiposi,posibilidad[u]);
}
posibilidad[B]++;
cantiposi[posibilidad[B]]++;
maxiposi=max(maxiposi,posibilidad[B]);
}
if(may3.size()>2){
//buscar al asegu
sort(may3.begin(),may3.end());
for(int i=0;i<may3.size();i++){
int con=0;
for(auto u:graph[may3[i]]){
if(binary_search(may3.begin(),may3.end(),u)){
con++;
}
}
if(con==may3.size()-1){
asegu=may3[i];
break;
}
}
if(asegu==-1){
canticriti=0;
return;
}else{
reinicar();
}
}else if(may3.size()==2){
if(canticiclo==1){
if(!(pertenececiclo[may3[0]] || pertenececiclo[may3[1]])){
canticriti=0;
return;
}else{
canticriti=cantiposi[maxiposi];
return;
}
/*if(pertenececiclo[may3[0]] && pertenececiclo[may3[1]]){
canticriti=2;
return;
}else if(pertenececiclo[may3[0]] || pertenececiclo[may3[1]]){
canticriti=1;
return;
}else{
canticriti=0;
return;
}*/
}else{
canticriti=2;
return;
}
}else if(may3.size()==1){
if(canticiclo==1){
if(pertenececiclo[may3[0]]){
canticriti=3;
return;
}else{
canticriti=0;
return;
}
}else{
canticriti=1+degree[may3[0]];
}
}else{
if(canticiclo==1){
canticriti=contaaa;
return;
}else{
//no pasa nada
}
}
}
}
}
int CountCritical(){return canticriti;}
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |