제출 #1150860

#제출 시각아이디문제언어결과실행 시간메모리
1150860enzyParachute rings (IOI12_rings)C++20
37 / 100
2329 ms168476 KiB
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int n, qm3, qm4, pai[maxn], ciclo, qtd4, caras[maxn], grau[maxn], tam, tira[maxn], qtd3, extra[maxn], te, maior;
vector<int>v[maxn];
void merge(int a, int b){
    pai[b]=a;
}

int find(int a){
    if(pai[a]==a) return a;
    return pai[a]=find(pai[a]);
}

void Init(int N_){
    n = N_;
    for(int i=0;i<n;i++){
        pai[i]=i;
        te=extra[i]=ciclo=qtd4=qtd3=qm4=qm3=tam=tira[i]=grau[i]=caras[i]=0;
        v[i].clear();
    }
}

void lenhadora(){
    set<pair<int,int>>s;
    for(int i=0;i<n;i++){
        grau[i]=v[i].size();
        for(int viz : v[i]) s.insert({i,viz}); 
    }
    queue<int>q;
    for(int i=0;i<n;i++) if(grau[i]==1) q.push(i);
    while(!q.empty()){
        int u=q.front(); q.pop();
        for(int viz : v[u]){
            if(s.count({u,viz})){
                grau[viz]--; grau[u]--;
                s.erase({u,viz}); s.erase({viz,u});
                if(grau[viz]==1) q.push(viz);
            }
        }
    }
    for(int i=0;i<n;i++){
        if(grau[i]){
            assert(grau[i]==2);
            caras[i]++;
            tam++;
        }
    }
}

void Link(int a, int b){
    v[a].push_back(b);
    v[b].push_back(a);
    int na=find(a), nb=find(b);
    if(na==nb){ // irão formar um ciclo
        if(ciclo){ // ja tem ciclo
            if(caras[a]==0||caras[b]==0) ciclo++; // se um dos caras n fizer parte do ciclo cira-se um novo e acabou
            else{
                extra[a]++;
                extra[b]++;
                te++;
                maior=max(maior,extra[a]);
                maior=max(maior,extra[b]);
            }
        }else{ // nao tem ciclo
            lenhadora(); // descobir qm sao os caras do ciclo
            ciclo++;
        }
    }else merge(na,nb); // se não forem conexos, ligar eles
    if(v[a].size()==4) qtd4++;
    if(v[b].size()==4) qtd4++;
    if(v[a].size()>=4) qm4=a;
    if(v[b].size()>=4) qm4=b;
    // agr sabemos q tem apenas caras com grau 3 ou menos e há no máximo um ciclo
    if(v[a].size()==3){
        qtd3++; tira[a]++; // aumentando a qtd 
        for(int i : v[a]) tira[i]++; // aumentando a qtd 
        qm3=a;
    }
    if(v[b].size()==3){
        qtd3++; tira[b]++; // aumentando a qtd
        for(int i : v[b]) tira[i]++; // aumentando a qtd 
        qm3=b;
    }
}

int CountCritical(){
    if(qtd4>=2||ciclo>=2) return 0; // nao da pra ter cara critico
    if(qtd4){ // apenas qm4 pd ser resp
        if(tira[qm4]==qtd3&&caras[qm4]==ciclo&&extra[qm4]==te) return 1; // checa se tira tds com grau>=3 e se esta no ciclo (se tiver)
        else return 0;
    }
    if(qtd3){ // apenas qm3 e vizinhos pd ser resp
        int resp=0;
        // checa se tira tds com grau>=3 e se esta no ciclo (se tiver)
        for(int viz : v[qm3]) if(tira[viz]==qtd3&&caras[viz]==ciclo&&extra[viz]==te) resp++;
        if(tira[qm3]==qtd3&&caras[qm3]==ciclo&&extra[qm3]==te) resp++;
        return resp;
    }
    // td mundo tem grau<=2
    if(ciclo&&te){
        if(te==1) return 2;
        else if(maior==te) return 1;
        else return 0;
    }else if(ciclo) return tam; // se tem ciclo sao os caras do ciclo
    else return n; // se n pd ser qlqr cara
}
#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...