#include #include #include #include #include "graph.h" int read_adjacency_matrix(char *datafile, adjmatrix mat){ FILE *fp; int vertex_num; vindex src, dest; fp = fopen( datafile, "r" ); fscanf( fp, "%d\n", &vertex_num ); if ( vertex_num > N ) { fprintf( stderr, "##### このプログラムが扱えるのは頂点数が%d までのグラフです\n", N ); exit(1); } for (src = 0; src < vertex_num; src++) { for (dest = 0; dest < vertex_num; dest++) { fscanf( fp, "%d\n", &mat[src][dest] ); } } fclose( fp ); return vertex_num; } void add_edge( graph *g, vindex src, vindex dest ) { edgecell *edge = (edgecell *)malloc( sizeof( edgecell )); edge->destination = dest; edge->next = g->vtop[src].adjlist; g->vtop[src].adjlist = edge; } void translate_into_graph( adjmatrix mat, graph *g ) { vindex i, j; for(i=g->vertex_num-1; i>=0; i--){ g->vtop[i].adjlist=NULL; for(j=g->vertex_num-1; j>=0; j--){ if(mat[i][j]==true){ add_edge(g, i, j); } } } } void print_graph( graph *g ) { vindex v; printf( "digraph G {\n" ); printf( " size=\"14,10\"; node[fontsize=10,height=0.01,width=0.01]; edge[len=3.0];\n"); for (v = 0; v < g->vertex_num; v++) { edgecell *edge; for (edge = g->vtop[v].adjlist;edge != NULL; edge = edge->next) { printf( " %d -> %d;\n", v+1, edge->destination+1 ); } } printf( "}\n" ); } void free_graph( graph *g ) { vindex v; for (v = 0; v < g->vertex_num; v++) { edgecell *edge, *next_edge; for (edge = g->vtop[v].adjlist; edge != NULL; edge = next_edge) { next_edge = edge->next; free( edge ); } } } //2頂点間の経路判定 boolearn judge_way(graph *g, vindex start, vindex target){ static boolearn visited[N]; static unsigned int depth = 0; //Init if(!depth){ start--; target--; vindex iniv; for(iniv = 0; iniv < g->vertex_num; iniv++) visited[iniv] = false; } //Error if(depth == UINT_MAX){ fprintf( stderr, "内部エラー\n"); exit(1); } //Main visited[start] = true; edgecell *child; for(child = g->vtop[start].adjlist; child != NULL; child = child->next){ if(child->destination == target) return true; if(!visited[child->destination]){ depth++; if(judge_way(g, child->destination, target)){ depth--; return true; } depth--; } } return false; } //強連結{sc(strongly connecteed)}グラフの判定 boolearn judge_sc_graph(graph *g){ vindex v; for(v = 1; v <= g->vertex_num; v++) if(!(judge_way(g, v, (v%g->vertex_num)+1))) return false; return true; } //準オイラー{se(semi eularian)}グラフの判定 boolearn judge_se_graph(graph *g){ int reldeg[N] = {0}; vindex v, start = -1; edgecell *child; for(v = 0; v < g->vertex_num; v++){ for(child = g->vtop[v].adjlist; child != NULL; child = child->next){ reldeg[v]--; reldeg[child->destination]++; } } for(v = 0; v < g->vertex_num; v++){ if(reldeg[v] == -1){ if(start == -1) start = v; else return false; } else if(!(reldeg[v] == 0 || reldeg[v] == 1)){ return false; } } if(start == -1) start = 0; for(v = 0; v < g->vertex_num; v++){ if(v != start) if(!judge_way(g, start+1, v+1)) return false; } return true; }