int clique(lista l, grafo g){ unsigned int removed = 0; for (no n=primeiro_no(l); n!=NULL; n=proximo_no(n)) { vertice v = conteudo(n); if(v->removido == 0){ lista vizinhos = vizinhanca(v,0,g); unsigned int todos_nos = tamanho_lista(l) - removed - 1; for (no auxN=primeiro_no(vizinhos); auxN!=NULL; auxN=proximo_no(auxN)) { if(todos_nos == 0) break; vertice auxV = conteudo(auxN); if(auxV->removido == 0){ for (no verifiyNode=primeiro_no(l); verifiyNode!=NULL; verifiyNode=proximo_no(verifiyNode)) { vertice verifyVertice = conteudo(verifiyNode); if(verifyVertice->removido == 0){ if(strcmp(verifyVertice->nome,auxV->nome) == 0){ todos_nos--; break; } } } } } if(todos_nos != 0){ return 0; } } else{ removed ++; } } return 1; }
grafo escreve_grafo(FILE *output, grafo g) { if(!(g && output)) return NULL; vertice v; aresta a; no nv, na; fprintf( output, "strict %sgraph \"%s\" {\n\n", g->direcionado ? "di" : "", g->nome ); // Imprime vertices for( nv = primeiro_no(g->vertices); nv; nv = proximo_no(nv) ){ v = conteudo(nv); fprintf( output, " \"%s\"\n", v->nome ); } fprintf( output, "\n" ); // Imprime arestas lista la = arestas(g); const char *dir = g->direcionado ? "->" : "--"; for( na = primeiro_no(la); na; na = proximo_no(na) ){ a = conteudo(na); fprintf( output, " \"%s\" %s \"%s\"", nome_vertice(a->origem), dir, nome_vertice(a->destino) ); if( g->ponderado ) fprintf( output, " [peso=%ld]", a->peso ); fprintf( output, "\n" ); } fprintf( output, "}\n" ); destroi_lista(la, NULL); return g; }
static lista arestas( grafo g ) { lista la = constroi_lista(); if( !g ) return la; for( no nv = primeiro_no(g->vertices); nv; nv = proximo_no(nv) ){ vertice v = conteudo(nv); for( no na = primeiro_no(v->arestas_saida); na; na = proximo_no(na) ){ aresta a = conteudo(na); if( !busca_aresta(la, a->origem, a->destino) ) insere_lista( a, la ); } if( g->direcionado ) { for( no na = primeiro_no(v->arestas_entrada); na; na = proximo_no(na) ){ aresta a = conteudo(na); if( !busca_aresta(la, a->origem, a->destino) ) insere_lista( a, la ); } } } return la; }
grafo copia_grafo(grafo g) { struct grafo *ng = malloc(sizeof(struct grafo)); if( !ng ) return NULL; vertice v; no nv, na; ng->nome = malloc(sizeof(char) * strlen(nome_grafo(g)+1)); strcpy(ng->nome, g->nome); ng->vertices = constroi_lista(); for( nv = primeiro_no(g->vertices); nv; nv = proximo_no(nv) ){ vertice vt = malloc(sizeof(struct vertice)); v = conteudo(nv); vt->nome = malloc(sizeof(char) * strlen(nome_vertice(v))+1); strcpy(vt->nome, nome_vertice(v)); vt->visitado = v->visitado; vt->coberto = v->coberto; vt->arestas_saida = constroi_lista(); vt->arestas_entrada = constroi_lista(); insere_lista(vt, ng->vertices); } for( nv = primeiro_no(ng->vertices); nv; nv = proximo_no(nv) ){ vertice vd = conteudo(nv); vertice vo = busca_vertice(g->vertices, nome_vertice(vd)); for( na = primeiro_no(vo->arestas_saida); na; na = proximo_no(na) ){ aresta at = copia_aresta( conteudo(na), ng ); insere_lista(at, vd->arestas_saida); } if( g->direcionado ){ for( na = primeiro_no(vo->arestas_entrada); na; na = proximo_no(na) ){ aresta at = copia_aresta( conteudo(na), ng ); insere_lista(at, vd->arestas_entrada); } } } ng->direcionado = g->direcionado; ng->ponderado = g->ponderado; ng->n_vertices = g->n_vertices; ng->n_arestas = g->n_arestas; return ng; }
int remove_no(struct lista *l, struct no *rno, int destroi(void *)) { int r = 1; if (l->primeiro == rno) { l->primeiro = rno->proximo; if (destroi != NULL) { r = destroi(conteudo(rno)); } free(rno); l->tamanho--; return r; } for (no n = primeiro_no(l); n->proximo; n = proximo_no(n)) { if (n->proximo == rno) { n->proximo = rno->proximo; if (destroi != NULL) { r = destroi(conteudo(rno)); } free(rno); l->tamanho--; return r; } } return 0; }
//------------------------------------------------------------------------------ // static void desvisita_vertices(grafo g) { for( no n = primeiro_no(g->vertices); n; n = proximo_no(n) ){ vertice v = conteudo(n); v->visitado = 0; } return; }
static lista vizinhanca_entrada(vertice v){ lista viz = constroi_lista(); for (no n=primeiro_no(v->adjacencias_entrada); n!=NULL; n=proximo_no(n)) { adjacencia a = conteudo(n); insere_lista(a->v_origem, viz); } return viz; }
//------------------------------------------------------------------------------ // static void xor(lista la) { for( no n = primeiro_no(la); n; n = proximo_no(n) ){ aresta a = conteudo(n); a->coberta = !a->coberta; a->origem->coberto = 1; a->destino->coberto = 1; } return; }
static lista vizinhanca_saida(vertice v){ lista viz = constroi_lista(); for (no n=primeiro_no(v->adjacencias_saida); n!=NULL; n=proximo_no(n)) { if(n != NULL){ adjacencia a = conteudo(n); insere_lista(a->v_destino, viz); } } return viz; }
static aresta busca_aresta( lista l, vertice origem, vertice destino ) { if( !l ) return NULL; for( no n = primeiro_no(l); n; n = proximo_no(n) ){ aresta a = conteudo(n); if( (origem == a->origem) && (destino == a->destino) ) return a; } return NULL; }
//------------------------------------------------------------------------------ int pertence_lista(lista l, void *conteudo) { no v = primeiro_no(l); while(v){ if (!strcmp( ((vertice) v->conteudo)->nome, ((vertice) conteudo)->nome ) ) return 1; v = proximo_no(v); } return 0; }
grafo escreve_grafo(FILE *output, grafo g){ if(!g || !output) return NULL; Agraph_t *ag; Agsym_t *peso; char peso_s[MAX_STRING_SIZE]; //criando a string "peso" char p_str[5]; strcpy(p_str, "peso"); //cria uma string vazia pra usar como valor default do atributo peso char default_s[1]; default_s[0] = '\0'; if(g->direcionado) ag = agopen(g->nome, Agstrictdirected, NULL); else ag= agopen(g->nome, Agstrictundirected, NULL); if(g->ponderado) peso = agattr(ag, AGEDGE, p_str, default_s); Agnode_t **nodes = malloc(g->n_vertices * sizeof(Agnode_t*)); for(unsigned int i = 0; i < g->n_vertices; i++) nodes[g->vertices[i]->id] = agnode(ag, g->vertices[i]->nome, TRUE); for(unsigned int i = 0; i < g->n_vertices; i++){ vertice v = g->vertices[i]; for(no n = primeiro_no(v->adjacencias_saida); n != NULL; n = proximo_no(n)){ adjacencia viz = conteudo(n); Agedge_t *ae = agedge(ag, nodes[v->id], nodes[viz->v_destino->id], NULL, TRUE); if(g->ponderado){ sprintf(peso_s, "%ld", viz->peso); agxset(ae, peso, peso_s); } } } free(nodes); agwrite(ag, output); agclose(ag); agfree(ag, NULL); return g; }
static vertice busca_vertice(lista l, char *nome) { if( !l ) return NULL; if( !nome ) return NULL; for( no n = primeiro_no(l); n; n = proximo_no(n) ){ vertice v = conteudo(n); if( ! strcmp(nome, v->nome) ) return v; } return NULL; }
void parser_montar_arvore(struct lnode *no) { struct token *tk; if (no == NULL) return; tk = no->value; tree_node = tree_insert(&tree, tree_node, tk); if (parser_verificar_erro(&no)) parser_montar_arvore(no); else parser_montar_arvore(proximo_no(no)); }
//------------------------------------------------------------------------------ static int busca_aresta(Agedge_t *a){ for ( no n=primeiro_no(lista_arestas); n; n=proximo_no(n)) { Agedge_t *aresta = conteudo(n); if ( ageqedge(a, aresta) ) return 1; } return 0; }
//------------------------------------------------------------------------------ // static grafo grafo_emparelhamento(grafo g) { grafo e = malloc(sizeof(struct grafo)); if( !e ) return NULL; e->nome = malloc(sizeof(char) * strlen(g->nome)+1); strcpy(e->nome, g->nome); e->direcionado = g->direcionado; e->ponderado = g->ponderado; e->vertices = constroi_lista(); for( no nv = primeiro_no(g->vertices); nv; nv = proximo_no(nv) ){ vertice ve = malloc(sizeof(struct vertice)); vertice vg = conteudo(nv); ve->nome = malloc(sizeof(char) * strlen(nome_vertice(vg))+1); strcpy(ve->nome, nome_vertice(vg)); ve->visitado = 0; ve->coberto = vg->coberto; ve->arestas_saida = constroi_lista(); ve->arestas_entrada = constroi_lista(); insere_lista(ve, e->vertices); } e->n_vertices = tamanho_lista(e->vertices); e->n_arestas = 0; for( no nv = primeiro_no(e->vertices); nv; nv = proximo_no(nv) ){ vertice ve = conteudo(nv); vertice vg = busca_vertice(g->vertices, nome_vertice(ve)); for( no na = primeiro_no(vg->arestas_saida); na; na = proximo_no(na) ){ aresta ag = conteudo(na); if (ag->origem != vg) continue; if( ag->coberta ){ aresta ae = copia_aresta( ag, e ); insere_lista(ae, ae->destino->arestas_saida); insere_lista(ae, ae->origem->arestas_saida); e->n_arestas++; } } } return e; }
int destroi_lista(lista l, int destroi(void *)) { no p; int ok = 1; while ( (p = primeiro_no(l)) ) { l->primeiro = proximo_no(p); if ( destroi ) ok &= destroi(conteudo(p)); free(p); } free(l); return ok; }
//------------------------------------------------------------------------------ int destroi_lista(lista l, int destroi(void *)) { if ( !l ) return 0; no prox; for (no n=primeiro_no(l); n; n=prox) { prox = proximo_no(n); if (destroi) destroi(conteudo(n)); free(n); } free(l); return 1; }
//------------------------------------------------------------------------------ // static int busca_caminho(vertice v, lista l, int last) { // essa função é chamada pela função que tenta achar um caminho aumentante // pra cada vértice não coberto (e retorna assim que achar) // e last é inicialmente 1, pois a primeira aresta será 0 (não coberta) if ( !v->coberto && !v->visitado ) { return 1; // true } v->visitado = 1; lista la = v->arestas_saida; for( no n = primeiro_no(la); n; n = proximo_no(n) ){ aresta a = conteudo(n); if (a->coberta == last) continue; vertice outro = a->origem == v ? a->destino : a->origem; if (!outro->visitado && busca_caminho(outro, l, !last)) { insere_lista(a, l); return 1; // true } } return 0; //false }
lista vizinhanca(vertice v, int direcao, grafo g) { lista la, lv = constroi_lista(); if( !v || !g ) return lv; switch( direcao ){ case 0 : la = v->arestas_saida; break; case 1 : la = v->arestas_saida; break; case -1 : la = v->arestas_entrada; break; } for( no n = primeiro_no(la); n; n = proximo_no(n) ){ aresta a = conteudo(n); if( v == a->origem ){ insere_lista( a->destino, lv ); } if( v == a->destino ){ insere_lista( a->origem, lv ); } } return lv; }
//------------------------------------------------------------------------------ // static lista caminho_aumentante(grafo g) { if( !g ) return NULL; lista l; for( no n = primeiro_no(g->vertices); n; n = proximo_no(n) ){ vertice v = conteudo(n); if( !v->coberto ) { v->visitado = 1; l = constroi_lista(); if( busca_caminho(v, l, 1) ) { return l; } else { printf("busca deu errado\n"); desvisita_vertices(g); destroi_lista(l, NULL); } } } desvisita_vertices(g); return NULL; }
//------------------------------------------------------------------------------ static void mostra_arestas(void) { if ( !n_arestas ) return; char rep_aresta = direcionado ? '>' : '-'; for ( no n=primeiro_no(lista_arestas); n; n=proximo_no(n)) { Agedge_t *a= conteudo(n); char *peso = agget(a, (char *)"peso"); printf(" \"%s\" -%c \"%s\"", agnameof(agtail(a)), rep_aresta, agnameof(aghead(a)) ); if ( peso && *peso ) printf(" [peso=%s]", peso); printf("\n"); } }
//------------------------------------------------------------------------------ int main(void) { struct grafo *g, *d, *c; struct vertice *v; struct no *n; lista l; g = le_grafo(stdin); escreve_grafo(stdout, g); if((l = ordena(g)) != NULL) { for(n = primeiro_no(l); n != NULL; n = proximo_no(n)) { v = (struct vertice *) conteudo(n); fprintf(stdout, "%s\n", nome_vertice(v)); } destroi_lista(l, nao_destroi_nos); } if((l = componentes(g)) != NULL) { for(n = primeiro_no(l); n != NULL; n = proximo_no(n)) { c = (struct grafo *) conteudo(n); escreve_grafo(stdout, c); } destroi_lista(l, destroi_grafo); } d = arvore_geradora_minima(g); if(d != NULL) { escreve_grafo(stdout, d); destroi_grafo(d); } /* d = arborescencia_caminhos_minimos(g, v); if(d != NULL) { escreve_grafo(stdout, d); destroi_grafo(d); } */ d = distancias(g); if(d != NULL) { escreve_grafo(stdout, d); destroi_grafo(d); } fprintf(stdout, "Diametro = %ld\n", diametro(g)); if(conexo(g)) { fprintf(stdout, "Conexo!\n"); } else { fprintf(stdout, "Não é conexo!\n"); } if(fortemente_conexo(g)) { fprintf(stdout, "Fortemente conexo!\n"); } else { fprintf(stdout, "Não é fortemente conexo!\n"); } /*if((l_blocos = blocos(g)) != NULL) { fprintf(stderr, "\n--Blocos criados:\n" ); for(n = primeiro_no(l); n != NULL; n = proximo_no(n)) { c = (struct grafo *) conteudo(n); escreve_grafo(stdout, c); } destroi_lista(l_blocos, destroi_grafo); }*/ destroi_grafo(g); return 0; }
//------------------------------------------------------------------------------ grafo grafo_induzido_vertice(grafo g, lista vertices){ no w; vertice u, v; aresta_t a, nova_aresta, nova_lista_aresta; // cria grafo grafo g_induzido = (grafo) malloc(sizeof(struct grafo)); g_induzido->tipo = NAODIRECIONADO; g_induzido->peso = g->peso; g_induzido->n_vertices = tam_lista(vertices); g_induzido->vertice = (vertice) malloc( (unsigned int)g_induzido->n_vertices * sizeof(struct vertice)); //Copia nome do grafo g_induzido->nome = (char *) malloc(strlen(g->nome)+1); strcpy(g_induzido->nome, g->nome); w = primeiro_no(vertices); int i = 0; // Copia vertices while(w != NULL){ v = conteudo(w); // copia nome g_induzido->vertice[i].nome = (char *) malloc(strlen(v->nome)+1); strcpy(g_induzido->vertice[i].nome, v->nome); // seta prox. vertice if (i != tam_lista(vertices) ) g_induzido->vertice[i].next = &g_induzido->vertice[i+1]; // inicializa lista de arestas g_induzido->vertice[i].aresta = v->aresta; i++; w = proximo_no(w); } g_induzido->vertice[i-1].next = NULL; //copia arestas // percorre vertices do grafo for (v = g_induzido->vertice; v; v = v->next){ nova_lista_aresta = NULL; // percore vizinhanco de v for (a = v->aresta; a; a = a->next){ if( (u = pertence_grafo(g_induzido, a->vertice)) != NULL ){ // aloca aresta nova_aresta = (aresta_t) malloc(sizeof(struct aresta_t)); // insere aresta na fila nova_aresta->next = nova_lista_aresta; nova_lista_aresta = nova_aresta; // copiar aresta nova_aresta->vertice = u ; if(g_induzido->peso) nova_aresta->peso = a->peso; } } // adiciona nova lista v->aresta = nova_lista_aresta; } return g_induzido; }