九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
用Dijkstra算法輸出最短路徑以及對應的最小權值
userphoto

2016.06.24

關注

    看《數(shù)據(jù)結構》的時候,發(fā)現(xiàn)教科書上提供的算法貌似只是把最短路徑上的頂點放到一個二維數(shù)組里頭就完事了,卻沒有給出路徑上頂點的輸出次序。一個頂點數(shù)組就叫做最短路徑,編者也太不負責任了吧,好歹也給個根據(jù)得到的路徑頂點數(shù)組求該路徑的方法吧?還是編者想讓讀者有自己思考的余地??不過回頭想想,如果通過那個路徑頂點的二維數(shù)組,按照路徑長度從小到大,輸出長路徑時先輸出短路徑包含的頂點的原則來分別輸出這些路徑,應該還是能搞定的(雖然沒試過……)。

        不過,自己還是重新寫了一個與教科書有點不同的Dijkstra算法出來,算法基本思想還是一樣的,只是這里的輔助變量有些區(qū)別而已,同時也給出了一個利用棧來求最短路徑中頂點的輸出次序。程序在VC++6.0編譯通過了,而算法的具體過程如下:

#include
#include
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef char VertexType;//頂點類型
#define INFINITY 2147483647//表示兩頂點不相連的權值為2147483647
#define MAX_VERTEX_NUM 20//表示圖中最大頂點數(shù)
#define MAX_STACK_NUM MAX_VERTEX_NUM

typedef struct Stack{
int vertex[MAX_STACK_NUM];
int top;
}Stack;

//棧初始化
Status InitStack(Stack *s){
int i;
for(i=0;i<>
   s->vertex[i]=0;
s->top=-1;
return OK;
}

//入棧
Status Push(Stack *s,int v){
if(s->top==MAX_STACK_NUM-1){
   printf('棧滿,無法入棧!\n');
   return ERROR;
}
s->vertex[++s->top]=v;
return OK;
}

//退棧
Status Pop(Stack *s,int *e){
if(s->top==-1){
   printf('空棧無法彈出!\n');
   return ERROR;
}
*e=s->vertex[s->top--];
return OK;
}

//判斷棧是否為空
Status StackEmpty(Stack s){
if(s.top==-1)
   return TRUE;
return FALSE;
}

typedef struct MGraph{
VertexType vexs[MAX_VERTEX_NUM];//頂點數(shù)組
int adj[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//圖的鄰接矩陣
int vexnum,arcnum;
}MGraph;

//頂點定位,不存在則返回-1
int LocateVex(MGraph G,VertexType v){
int i;
for(i=0;i<>
   if(G.vexs[i]==v)
    return i;
   return -1;
}

//建立無向圖鄰接矩陣
Status CreateGraph(MGraph *G){
VertexType v1,v2;
int i,j,k;

printf('構造有向圖\n\n');
printf('請輸入頂點個數(shù):');
scanf('%d',&G->vexnum);
if(G->vexnum>MAX_VERTEX_NUM) return ERROR;
printf('輸入邊數(shù):');
scanf('%d',&G->arcnum);
if(G->arcnum>MAX_VERTEX_NUM*(MAX_VERTEX_NUM-1)/2) return ERROR;//邊輸入有誤
printf('\n');

for(i=0;ivexnum;++i){
   getchar();
   printf('輸入第%d個頂點:',i+1);
   scanf('%c',&G->vexs[i]);
}

for(i=0;ivexnum;++i)
   for(j=0;jvexnum;++j)
    G->adj[i][j]=INFINITY;//鄰接矩陣初始化
   printf('\n');
  
   for(k=0;karcnum;++k){
    getchar();
    printf('輸入第%d條邊對應的起點和終點:',k+1);
    scanf('%c%c',&v1,&v2);
    i=LocateVex(*G,v1);
    j=LocateVex(*G,v2);
    printf('輸入該邊的權值:');
    scanf('%d',&G->adj[i][j]);
   }
   return OK;
}

//返回v的第一個鄰接點位置,不存在則返回-1
int FirstAdjVex(MGraph G,int v){
int j;
for(j=0;j<>
   if(G.adj[v][j]==1)
    return j;
   return -1;
}

//返回v相對于w的下一個鄰接點,沒有則返回-1
int NextAdjVex(MGraph G,int v,int w){
int k;
for(k=w+1;k<>
   if(G.adj[v][k]==1)
    return k;
   return -1;
}

//打印鄰接矩陣
void Print_Graph_Array(MGraph g){
int i,j;
printf('\n圖鄰接矩陣是:\n ');
for(i=0;i<>
   printf(' %c',g.vexs[i]);
for(i=0;i<>
   printf('\n%c ',g.vexs[i]);
   for(j=0;j<>
    if(g.adj[i][j]==INFINITY)
     printf('%d ',g.adj[i][j]-INFINITY);
    else
     printf('%d ',g.adj[i][j]);
   }
}
printf('\n\n');
}

//Dijkstra算法
void ShortestPath_Dij(MGraph g,int v0,int D[],int P[]){
//D[]存放到達各個頂點的最小權值之和
//路徑數(shù)組P[]用于求各個頂點最短路徑中頂點的先后次序,如果P[i]不等于i,則表示在最短路徑中到達點vi前必須先到達點v(P[i])

int i,j;
int location_min,min;//location_min存放每一次“路徑試探”時找到的最小權值min對應的頂點的下標
int final[MAX_VERTEX_NUM];//數(shù)組final[i]為true當且僅當vi已經(jīng)找到從v0出發(fā)的最短路徑

for(j=0;j<>
   D[j]=g.adj[v0][j];//數(shù)組D[]初始化
   final[j]=FALSE;//數(shù)組final[]初始化
  
   //數(shù)組P[]初始化
   if(g.adj[v0][j]!=INFINITY)
    P[j]=j;
   else
    P[j]=INFINITY;
}
final[v0]=TRUE;

for(i=1;i<>
   min=INFINITY;

   //求每一次“路徑試探”時最小權值對應的頂點的下標,并保存到location_min中
   for(j=0;j<>
    if(final[j]) continue;
    if(D[j]
     min=D[j];
     location_min=j;
    }
   }
   final[location_min]=TRUE;
  
   //試探vertex[location_min]到其余的某個頂點vertex[j]的權值與D[location_min]之和是否小于D[j]
   for(j=0;j<>
    if(final[j]) continue;
    if(g.adj[location_min][j]!=INFINITY && D[location_min]+g.adj[location_min][j]<>
     D[j]=D[location_min]+g.adj[location_min][j];
     P[j]=location_min;
    }
   }

}

//根據(jù)求得的路徑數(shù)組P[]依次打印各條最短路徑的線路及其最小權值和
void Print_ShortestPaths(MGraph g,int v0,int D[],int P[],int vertexnum){
int i,j;
int e;
Stack s;

for(i=0;i<>
   if(i==v0) continue;

   printf('%c到%c的最短路徑是:',g.vexs[v0],g.vexs[i]);
   if(P[i]==INFINITY) 
    printf('無\n\n');
   else{
    j=i;
    InitStack(&s);
    Push(&s,j);
    while(g.vexs[j]!=g.vexs[P[j]]){
     Push(&s,P[j]);
     j=P[j];
    }//如果g.vexs[j]與g.vexs[P[j]]不相等,則表示在最短路徑中輸出頂點g.vexs[j]前要先輸出頂點g.vexs[p[j]]
    Push(&s,v0);
    while(!StackEmpty(s)){
     Pop(&s,&e);
     printf('%c ',g.vexs[e]);
    }
    printf('\n該路徑的總權值為:%d\n\n',D[i]);
   }//從路徑的終點到起點依次進棧,最后通過棧將路徑的各頂點輸出
}
}


void main(){
MGraph g;
char quit;
VertexType startpoint;
int v0;
int D[MAX_VERTEX_NUM],P[MAX_VERTEX_NUM];
Stack s;

do {
   if(!CreateGraph(&g)){
    printf('輸入錯誤!\n');
    goto ErrMrk;
   }
  
   Print_Graph_Array(g);

   printf('輸入路徑起點:');
   getchar();
   startpoint=getchar();
   printf('\n');
   v0=LocateVex(g,startpoint);
   ShortestPath_Dij(g,v0,D,P);//求起點到各個頂點的最短路徑
   Print_ShortestPaths(g,v0,D,P,g.vexnum);//打印各條最短路徑及相應的總權值
  
   printf('\n\n');

ErrMrk: printf('退出請按0,重新測試請按任意鍵:');
   getchar();
   quit=getchar();
   system('cls');
} while(quit!='0');
}


本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
最小支撐樹的prim算法(反圈法)c++實現(xiàn)
C語言圖的創(chuàng)建
基于鄰結矩陣的圖的BFS和DFS遍歷
算法
單源最短路徑(1):Dijkstra算法
【算法復習二】傳統(tǒng)基本算法(貪心、動態(tài)規(guī)劃、回溯和分支限界)
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服