#include <cstdio> #include <iostream> #include <vector> #include <algorithm> #include <set> #include <stack> #include <queue> using namespace std; typedef vector<int> VI; typedef vector<VI> VVI; VVI mat, mate; int v; typedef vector<int> Face; multiset<Face> faces; vector<bool> inface; VI maiorciclo; VI cicloatual; vector<bool> incluido; bool planar; void auxencontra(int x){ if(!maiorciclo.empty()) return; for(int i=0; i<v; ++i){ if(!mat[x][i] || incluido[i]) continue; incluido[i]=true; cicloatual.push_back(i); auxencontra(i); incluido[i]=false; cicloatual.pop_back(); } if(maiorciclo.empty() && cicloatual.size()==v){ maiorciclo=cicloatual; } } vector<int> encontra_ciclo(){ maiorciclo = VI(); cicloatual = VI(); incluido = vector<bool>(v, false); auxencontra(0); return maiorciclo; } vector<bool> fragatual; void inicializar(){ inface = vector<bool>(v, false); vector<int> ciclo = encontra_ciclo(); Face f; puts("CICLO"); for(int i=0; i<ciclo.size(); ++i){ int a = ciclo[i]; int b = ciclo[(i+1)%ciclo.size()]; mate[a][b]=mate[b][a]=1; printf("%d ", a); f.push_back(a); inface[a]=true; } faces.insert(f); //interna faces.insert(f); //externa ou vice-versa } void insereface(int x, int y, Face f){ faces.erase(faces.find(f)); Face f1, f2; f1.push_back(y); f1.push_back(x); f2.push_back(y); f2.push_back(x); mate[x][y]=mate[y][x]=1; int p; for(p=0; p<f.size(); p++){ if(f[p]==x) break; } puts("Isto cria 2 NOVAS FACES"); for(int i=(p+1)%f.size(); f[i]!=y; i=(i+1)%f.size()){ f1.push_back(f[i]); } for(int i=(p-1+f.size())%f.size(); f[i]!=y; i=(i-1+f.size())%f.size()){ f2.push_back(f[i]); } for(int i=0; i<f1.size(); ++i) printf("%d ", f1[i]); puts(""); for(int i=0; i<f2.size(); ++i) printf("%d ", f2[i]); puts(""); faces.insert(f1); faces.insert(f2); } bool cordalseg(){ Face any = Face(); int xg, yg; for(int i=0; i<v; ++i){ for(int j=i+1; j<v; ++j){ if(!mate[i][j] && mat[i][j]){ //PARA CADA ARESTA int qtd=0; Face pri; int x, y; for(multiset<Face>::iterator f = faces.begin(); f!=faces.end(); ++f){ //PARA CADA FACE Face aux = (*f); bool xi=false, yi=false; for(int k=0; k<aux.size(); ++k){ if(aux[k]==i){ xi=true; } if(aux[k]==j){ yi=true; } if(xi && yi) break; } if(xi && yi){ if(!qtd){ pri = aux; x = i; y = j; } qtd++; } } if(qtd==0){ planar = false; return false; } else if(qtd==1){ printf("Insere %d %d na face: ", x, y); for(int i=0; i<pri.size(); ++i) printf("%d ", pri[i]); puts(""); insereface(x,y,pri); return true; } else if(qtd>=2){ puts(">=2"); if(any.empty()){ printf("! %d %d\n", x, y); for(int i=0; i<pri.size(); ++i) printf(" %d", pri[i]); puts(""); any = pri; xg=x; yg=y; } } } } } if(!any.empty()){ printf("Insere %d %d na face: ", xg, yg); for(int i=0; i<any.size(); ++i) printf("%d ", any[i]); puts(""); insereface(xg,yg,any); return true; } planar = true; return false; } void planarity(){ inicializar(); int cont = 0; do{ printf("\nNa Iteracao %d existem as FACES\n", cont++); for(multiset<Face>::iterator f = faces.begin(); f!=faces.end(); f++){ for(int i=0; i<(*f).size(); ++i) printf("%d ", (*f)[i]); puts(""); } }while(cordalseg()); puts("\nFACES FINAIS"); for(multiset<Face>::iterator f = faces.begin(); f!=faces.end(); f++){ for(int i=0; i<(*f).size(); ++i) printf("%d ", (*f)[i]); puts(""); } } int main(){ scanf("%d", &v); mat = VVI(v, VI(v, 0)); mate = VVI(v, VI(v, 0)); int a, b; while(scanf("%d %d", &a, &b)!=EOF){ if(!a and !b) break; mat[a][b]=mat[b][a]=1; } planarity(); if(!planar){ printf("\nInfelizmente, nem todas as arestas puderam ser inseridas na imersao planar!\nAbaixo segue a lista das arestas que nao puderam ser colocadas:\n"); for(int i=0; i<v; ++i){ for(int j=i+1; j<v; ++j){ if(mat[i][j] != mate[i][j]) printf("%d -> %d\n", i, j); } } }else{ puts("\nGRAFO PLANAR"); } }