Bellman 算法实现
生活随笔
收集整理的這篇文章主要介紹了
Bellman 算法实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
樣例輸入:
7
0 1 6
0 2 5
0 3 5
1 4 -1
2 1 -2
2 4 1
3 2 -2
3 5 -1
4 6 3
5 6 3
-1 -1 -1
樣例輸出
1 0→3→2→1
3 0→3→2
5 0→3
0 0→3→2→1→4
4 0→3→5
3 0→3→2→1→4→6
?
?
#include <stdio.h> #include <string.h> #define INF 1000000 //無窮大 #define MAXN 20 //頂點個數最大值int n; //頂點個數 int Edge[MAXN][MAXN]; //鄰接矩陣 int dist[MAXN]; // int path[MAXN]; // void Bellman( int v0 ) //求頂點v0到其他頂點的最短路徑 {int i, j, k, u; //循環變量for( i=0; i<n; i++ )//初始化 {dist[i] = Edge[v0][i];if( i!=v0 && dist[i]<INF ) path[i] = v0;else path[i] = -1;}for( k=2; k<n; k++ ) //從dist(1)[u]遞推出dist(2)[u], …,dist(n-1)[u] {for( u=0; u<n; u++ ) //修改每個頂點的dist[u]和path[u] {if( u != v0 ){for( j=0; j<n; j++ )//考慮其他每個頂點 {//頂點j到頂點u有直接路徑,且途經頂點j可以使得dist[u]縮短if( Edge[j][u] < INF && dist[j] + Edge[j][u] < dist[u] ){dist[u] = dist[j] + Edge[j][u];path[u] = j;}}//end of for}//end of if}//end of for}//end of for }int main( ) {int i, j; //循環變量int u, v, w; //邊的起點和終點及權值scanf( "%d", &n ); //讀入頂點個數nwhile( 1 ){scanf( "%d%d%d", &u, &v, &w ); //讀入邊的起點和終點if( u==-1 && v==-1 && w==-1 ) break;Edge[u][v] = w; //構造鄰接矩陣 }for( i=0; i<n; i++ ) //設置鄰接矩陣中其他元素的值 {for( j=0; j<n; j++ ){if( i==j ) Edge[i][j] = 0;else if( Edge[i][j]==0 ) Edge[i][j] = INF;}}Bellman( 0 ); //求頂點0到其他頂點的最短路徑int shortest[MAXN]; //輸出最短路徑上的各個頂點時存放各個頂點的序號for( i=1; i<n; i++ ){printf( "%d\t", dist[i] ); //輸出頂點0到頂點i的最短路徑長度//以下代碼用于輸出頂點0到頂點i的最短路徑memset( shortest, 0, sizeof(shortest) );int k = 0; //k表示shortest數組中最后一個元素的下標shortest[k] = i;while( path[ shortest[k] ] != 0 ){k++; shortest[k] = path[ shortest[k-1] ];}k++; shortest[k] = 0;for( j=k; j>0; j-- )printf( "%d→", shortest[j] );printf( "%d\n", shortest[0] );}return 0; }?用vertor實現Bellman:
#include<iostream> #include<vector> using namespace std; const int N = 100; const int INF = 0x3f3f3f3f;struct Edge{ //用于記錄一組關系int u,v,w; };vector<Edge> edge; //用于保存圖的關系 int dis[N]; //源點到各點的最短距離 int path[N]; //源點到各點的路徑 int road[N]; //用于逆向追中輸出路徑void init(){while(!edge.empty()){edge.clear();} }void Bellman_Ford_vector(int v,int n,int m){ //源點,定點數,邊數int i,j;memset(path,255,sizeof(path)); //初始化路徑為-1;for(i=0;i<=n;i++){ //初始化dis[i]為不可到達dis[i] = INF;}dis[v] = 0; //把源點到自己的路徑改為0for(i=0;i<n;i++){ //第一層循環,由dis0遞推出dis1~nfor(j=0;j<m;j++){ //判斷邊<u,v>的引入能否縮短源點到v的距離if(dis[edge[j].u] + edge[j].w < dis[edge[j].v]){ //若可以松弛,更新dis[edge[j].v] = dis[edge[j].u] + edge[j].w;path[edge[j].v] = edge[j].u;}}} }int main(){freopen("in.txt","r",stdin);int n;Edge temp;while(scanf("%d",&n)!=EOF){init();while(scanf("%d%d%d",&temp.u,&temp.v,&temp.w) && ~temp.u && ~temp.v && ~temp.w){edge.push_back(temp); //把關系添加到vector }Bellman_Ford_vector(0,n,edge.size());for(int i=1;i<n;i++){printf("%d\t",dis[i]); //輸出最短路int k=0; //用于標記要經過幾個點road[k] = i; //保存第一個點while(path[road[k]] != -1){//若還有前繼點,逆向追蹤k++;road[k] = path[road[k-1]];}while(k){ //輸出路徑printf("%d->",road[k--]);}printf("%d\n",road[k]);}}return 0; }?
轉載于:https://www.cnblogs.com/Deng1185246160/p/3223236.html
總結
以上是生活随笔為你收集整理的Bellman 算法实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring REST
- 下一篇: .net面试题目51-100