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

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

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

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

Q&A

解決済

2回答

807閲覧

プリム法の出力結果が模範解答と異なるので困っています。

Teemro_431265

総合スコア29

C

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

0グッド

1クリップ

投稿2019/01/27 02:11

編集2019/01/27 02:18

プリム法について勉強について勉強しているのですが入力が100×100隣接行列の時に結果が少しだけ異なってしまいます。
問題としては最小全域木で与えられた重み付きグラフに対する最小全域木の辺の重みの総和を計算するプログラムを作成すると言うものです。
Prims関数に関して何かおかしなところがあれば教えていただきたいです。
問題はこちらです。
問題
うまくいかない入力例はこちらです。
入力例

本来なら出力結果が
3864
となるはずなのですが
3991
となってしまいます。

c

1#include<stdio.h> 2#define max 1000 3#define inf 100000 4 5int vertex_num,admat[max][max]; 6 7int Prims(){ 8 int i,j,u,v,cost[max][max],min_distance; 9 int visit[max],no_edges,min_cost,distance[max],from[max]; 10 11 for(i=0;i<vertex_num;i++){ 12 for(j=0;j<vertex_num;j++){ 13 if(admat[i][j]==0){ 14 cost[i][j]=inf; 15 }else{ 16 cost[i][j]=admat[i][j]; 17 } 18 } 19 } 20 distance[0]=0; 21 visit[0]=1; 22 23 for(i=1;i<vertex_num;i++){ 24 distance[i]=cost[0][i]; 25 from[i]=0; 26 visit[i]=0; 27 } 28 min_cost=0; 29 no_edges=vertex_num-1; 30 31 while(no_edges>0){ 32 min_distance=inf; 33 for(i=1;i<vertex_num;i++){ 34 if(visit[i]==0 && distance[i]<min_distance){ 35 v=i; 36 min_distance=distance[i]; 37 } 38 } 39 u=from[v]; 40 no_edges--; 41 visit[v]=1; 42 for(i=1;i<vertex_num;i++){ 43 if(visit[i]==0 && cost[i][v]<distance[i]){ 44 distance[i]=cost[i][v]; 45 from[i]=v; 46 } 47 } 48 min_cost+=cost[u][v]; 49 } 50 51 return min_cost; 52} 53 54int main(){ 55 //admatは隣接行列 56 int i,j; 57 58 scanf("%d",&vertex_num); 59 for(i=0;i<vertex_num;i++){ 60 for(j=0;j<vertex_num;j++){ 61 scanf("%d",&admat[i][j]); 62 } 63 } 64 for(i=0;i<vertex_num;i++){ 65 for(j=0;j<vertex_num;j++){ 66 if(admat[i][j]==-1){ 67 admat[i][j]=0; 68 } 69 //printf("%d ",admat[i][j]); 70 } 71 } 72 73 printf("%d\n",Prims()); 74 return 0; 75} 76

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

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

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

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

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

guest

回答2

0

回答ではないですが、

C言語のコードを組みたいのであれば、デバッグ環境を整えましょう
WindowsであればVisualStudio、そうでなければEclipseなど、
これらの統合環境では、C言語のコードの任意の行で実行を停止させ、変数の値を参照したり、1行づつステップ実行させて変数の値を追いかけるなどができるようになります
そうすれば、あてずっぽでコードを組む、ということをしなくて済みます

投稿2019/01/27 06:06

y_waiwai

総合スコア87774

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

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

Teemro_431265

2019/01/27 06:20

あてずっぽでコードは組んでません。
y_waiwai

2019/01/27 06:34

ソースデバッグできる環境をお持ちなら、どこで計算がおかしくなっていっているのか、というのを探っていきましょう。 すでにそういうことはやってる、というのであれば、この回答は無視してください。 #で、できればどこでおかしいのかというのを追記していただけるとありがたいです
pepperleaf

2019/01/27 13:21

これ、ちょっと追ってみたけど、単純にデバッグ環境があるからと言ってデバッグできるとは思えない。 プリム法に関する知識が無いと厳しそう。コードそのものは、デバッガなんか無しでも追跡は容易。ただし、意味するところが、、。ちょっと調べてみたが、まだ理解できず。 あ、Visual Studio 2017 の cl でコンパイルしたら、実行時にエラー無し終了。どうもstackサイズオーバーか? ローカルをグローバルに移して実行できました。
guest

0

ベストアンサー

C

1 for(i=0;i<vertex_num;i++){ 2 for(j=0;j<vertex_num;j++){ 3 if(admat[i][j]==-1){ 4 admat[i][j]=0; 5 } 6 //printf("%d ",admat[i][j]); 7 } 8 }

が間違いでは?

参照ページの制約条件に

0≤aij≤2,000 (aij≠−1 のとき)

があります。
上記箇所を削除すると共に、

C

1 if(admat[i][j]==0){ 2 cost[i][j]=inf;

C

1 if(admat[i][j]==-1){ 2 cost[i][j]=inf;

とする。

手元の計算では、 3864 となりました。
(実際にうまくいかない入力例には、0が含まれています)

[追記]
結局、プリム法は理解できないまま。

投稿2019/01/27 15:03

編集2019/01/27 15:04
pepperleaf

総合スコア6383

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

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

Teemro_431265

2019/01/31 03:00

回答ありがとうございます。 まだ何が悪いのかはわかっていないので参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問