GRL_1_B Single Source Shortest Path (Negative Edges)
問題
単一始点最短経路 負の重み | グラフ | Aizu Online Judge
負のコストを持つエッジを含んだグラフの、最短経路問題です。ダイクストラ法はコストが非負でないと利用できません。
この場合、ベルマンフォード法が有効だそうです。下記のページが分かり易かったです。
Algorithm
ダイクストラ法は、到達コストが小さいノードから更新を行っていきますが、ベルマンフォード法では、各エッジに接続するノードから更新を行っていきます。
ダイクストラ→ノード ベルマンフォード→エッジ みたいな感じですね。
#include<stdio.h> #define LARGE 2000 #define INF 1000000000 #define MIN(a, b) ((a) < (b) ? (a) : (b)) int V,e; typedef struct edge{ int from; int to; int cost; }edge; int BellmanFord(edge E[],int C[]){ int i,j; int cnt=0; for(j=0;j<V-1;j++){ for(i=0;i<e;i++){ if(C[E[i].from]!=INF && C[E[i].to] > C[E[i].from]+E[i].cost){ C[E[i].to]=C[E[i].from]+E[i].cost; cnt++; } } } if(cnt>e){ printf("NEGATIVE CYCLE\n"); return 0; } return 1; } int main(){ int start; int s,t,d; int i,flg; int C[LARGE]; edge E[LARGE]; scanf("%d %d %d",&V,&e,&start); for(i=0;i<e;i++){ scanf("%d %d %d",&s,&t,&d); E[i].from=s; E[i].to=t; E[i].cost=d; } for(i=0;i<V;i++){ C[i]=INF; } C[start]=0; flg=BellmanFord(E,C); if(flg==0)return 0; for(i=0;i<V;i++){ if(C[i]==INF)printf("INF\n"); else printf("%d\n",C[i]); } return 0; }
先人の賢さに驚くばかりです。