質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1003閲覧

c言語 フラーリーのアルゴリズムによるオイラー小道の表示、橋確認時のエラー

tamintya

総合スコア34

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/06/18 07:27

全ての次数が偶数かどうかでオイラーグラフかを判定し、オイラーグラフの場合はフラーリーのアルゴリズムを用いてオイラー小道を表示したいのですが、橋ではないはずのところで橋だと判定されてしまい最後まで表示されません。
その原因と解決方法を知りたいです。

実行結果

***** pos = 0 next-hop candidate: 1 3 4 5 0-1 is not a bridge. ***** pos = 1 next-hop candidate: 2 4 5 1-2 is not a bridge. ***** pos = 2 next-hop candidate: 3 6 7 2-3 is not a bridge. ***** pos = 3 next-hop candidate: 0 6 7 3-0 is not a bridge. ***** pos = 0 next-hop candidate: 4 5 0-4 is not a bridge. ***** pos = 4 next-hop candidate: 1 5 7 4-1 is not a bridge. ***** pos = 1 next-hop candidate: 5 candidate is 1-5 only. ***** pos = 5 next-hop candidate: 0 4 6 5-0 is a bridge. Another candidate... 5-4 is a bridge. Another candidate... 5-6 is a bridge. Another candidate... 5-0 is a bridge. Another candidate... 5-0 is a bridge. Another candidate... 5-0 is a bridge. Another candidate... 5-0 is a bridge. Another candidate... 5-0 is a bridge. Another candidate... Segmentation fault

該当のソースコード

C

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4 5#define MAX_LEN 256 //ファイル名の最大値 6 7//連結か調べる 8void visit( int v, int *yet, int N, int **adjacent ) 9{ 10 int w; 11 yet[v] = 0; 12 for ( w=0; w<N; w++ ) 13 if ( adjacent[v][w] == 1 && yet[w] == 1 ) 14 visit( w, yet, N, adjacent ); 15} 16int connect_check( int N, int **adjacent ) 17{ 18 int i, 19 *YetToVisit, 20 count = 0; 21 YetToVisit = ( int * )malloc( sizeof( int ) * N ) 22; 23 for ( i=0; i<N; i++ ) 24 YetToVisit[i] = 1; 25 for ( i=0; i<N; i++ ) 26 if ( YetToVisit[i] == 1 ) { 27 count++; 28 visit( i, YetToVisit, N, adjacent ); 29 } 30 free( YetToVisit ); 31 return ( count ); 32} 33 34//振る舞いを決定 35int selection (int **adjacent, int next[], int min, int pos, int candidate){ 36 37 int check = 0; 38 39 adjacent[pos][next[min]] = 0; //接続の消去 40 adjacent[next[min]][pos] = 0; //接続の消去 41 42 check = connect_check(8,adjacent); //連結か確認 43 44 if(candidate == 1){ //候補が1つしかない場合 45 printf("candidate is %d-%d only.\n",pos,next[min]); 46 return min; 47 }else if(check != 1){ //橋の場合 48 printf("%d-%d is a bridge. Another candidate...\n",pos,next[min]);//橋であることを表示 49 adjacent[pos][next[min]] = 1; //接続の回復 50 adjacent[next[min]][pos] = 1; //接続の回復 51 52 selection(adjacent, next, min+1, pos, candidate); //次の候補で繰り返す 53 }else{ //橋ではない場合 54 printf("%d-%d is not a bridge.\n",pos,next[min]); 55 return min; 56 } 57} 58 59 60//経路の計算 61int fleury (int **adjacent, int pos){ 62 int j; 63 int min = 0; //候補の可能性のある最小の位置 64 int candidate = 0; //候補の数 65 int N = 8; //行列サイズ 66 int next[8] = {10,0,0,0,0,0,0,0}; //候補の配列 67 printf("*****\n"); 68 printf("pos = %d\n",pos); 69 printf("next-hop candidate:"); 70 for(j=0;j<N;j++){ //移動先の候補を表示 71 if(adjacent[pos][j] == 1){ 72 next[candidate] = j; //nextに点番号を入れる 73 printf(" %d",j); 74 candidate++; 75 } 76 } 77 78 printf("\n"); 79 80 81 82 min = selection(adjacent, next, min, pos, candidate); //移動できる最初の点番号獲得 83 84 85 if(next[0] != 10 ){ //候補が0個でないなら 86 fleury(adjacent,next[min]); 87 } 88 89} 90 91 92int main(int argc, char *argv[]) { 93 int i,j; 94 int n1,n2; //点番号の一時保存 95 int N,M = 0; //点の数、辺の数 96 FILE *fp; //ファイルポインタ 97 char fn[MAX_LEN]; //グラフファイル名 98 int **adjacent; //隣接行列 99 double dsum = 0; //次数の合計 100 int count = 0; //奇数の次数の数 101 102 int pos = 0; //現在の点 103 104 //実行時引数の数をチェック 105 if(argc != 2){ 106 fprintf(stderr, "Usage: %s graph_file\n", argv[0]); 107 exit(1); 108 } 109 110 //ファイル名をコピー 111 strcpy(fn, argv[1]); 112 113 //ファイルオープン 114 if((fp = fopen(fn, "r")) == NULL){ 115 fprintf(stderr, "%s cannot found./n", fn); 116 exit(1); 117 } 118 119 //1行目の読み込み 120 fscanf(fp, "%d", &N); 121 122 //隣接行列を動的に作成する N x N の2次元配列をmallocする 123 adjacent = (int **)malloc(sizeof(int *) * N); 124 for(i=0;i<N;i++){ 125 adjacent[i] = (int *)malloc(sizeof(int) * N); 126 for(j=0;j<N;j++){ 127 adjacent[i][j] = 0; 128 } 129 } 130 131 //2行目以降の読み込み 132 while(fscanf(fp, "%d %d", &n1,&n2) != EOF){ 133 M++; 134 adjacent[n1][n2] = 1; 135 adjacent[n2][n1] = 1; 136 } 137 138 fclose(fp); 139 140 //各次数の計算 141 int d[N]; //次数を格納する 142 for(i=0;i<N;i++){ 143 d[i] = 0; 144 } 145 for(i=0;i<N;i++){ 146 for(j=0;j<N;j++){ 147 if(adjacent[i][j] == 1){ 148 d[i]++; 149 dsum++; 150 } 151 } 152 if(d[i] % 2 == 1){ //奇数の場合 153 count++; 154 } 155 } 156 157 if(count == 0){ 158 fleury(adjacent,pos); //経路の表示 159 }else{ 160 printf("This is not Euler graph.\n"); 161 } 162 163 //メモリの開放 164 for(i=0;i<N;i++){ 165 free(adjacent[i]); 166 adjacent[i] = NULL; 167 } 168 free(adjacent); 169 170 return 0; 171}

###読み込むファイル

8 0 3 3 7 4 1 2 6 3 2 2 7 0 4 0 1 5 6 3 6 1 5 0 5 1 2 4 7 6 7 5 4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ある節点につながる辺がすべて削除された場合を考えてみてください。

connect_checkにて、YetToVisitにすべて1を入れているので、つながるすべての辺が削除された節点についても1が入ることになります。そうなると、その接点は他とつながっていないので、常に非連結と判断されてしまうのではないでしょうか。

投稿2022/06/18 10:58

actorbug

総合スコア2224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tamintya

2022/06/18 13:16

回答ありがとうございます。 ご指摘通りでしたので、つながる全ての辺が削除された節点には1を代入しないようにしたところ求めている結果になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問