1. 程式人生 > >[資料結構] 鄰接矩陣實現Dijkstra演算法

[資料結構] 鄰接矩陣實現Dijkstra演算法

#include <iostream>
using namespace std; 

#define MAX_V 100 //定義最大頂點個數
#define INF 1000 //表示正無窮 


typedef struct VertexType
{
    int number;//頂點標號
    //int weight;
};//頂點型別

typedef struct MGraph//圖的定義
{
    int matrix[MAX_V][MAX_V];//鄰接矩陣
    int weight[MAX_V][MAX_V];//存放權值 
    int v;//頂點數
	int e;//邊數
    VertexType vertax[MAX_V];//存放頂點資訊
};//圖的鄰接矩陣型別

void CreateMGragh(MGraph *G)
{
	int i,j,m,weight;
	cout << "請輸入頂點數和邊數:" << endl;
	cin >> G->v >> G->e ;
	cout << "請輸入頂點資訊:" << endl;
	for (i=0;i<G->v;i++)
	  scanf("%d",&G->vertax[i].number);//輸入頂點資訊,建立頂點表
	
	for (i=0;i<G->v;i++)//初始化鄰接矩陣 
	  for (j=0;j<G->v;j++)
      { 
		  G->matrix[i][j]=0;
		  G->weight[i][j]=INF;//讓所有權值不存在 
      }
    
	for(i=0;i<G->v;i++)//是結點自身指向自身權值為0 
	  for(j=0;j<G->v;j++)
	    if(i==j)
	      G->weight[i][j]=0;
	
	cout << "輸入每條有向邊的首尾頂點序號及權值:" << endl;
	for (m=0;m<G->e;m++)
	{
		cin >> i >> j >> weight;
		G->matrix[i][j]=1;
		G->weight[i][j]=weight;
	}	
}

void DisplayMGragh(MGraph *G)//輸出鄰接矩陣G
{
    int i,j;
    for(i=0;i<G->v;i++)
    {
        for(j=0;j<G->v;j++)
          printf("%5d",G->matrix[i][j]);
        printf("\n");
    }
}

void DisplayMGragh_W(MGraph *G)//輸出權值矩陣G
{
    int i,j;
    for(i=0;i<G->v;i++)
    {
        for(j=0;j<G->v;j++)
          printf("%5d",G->weight[i][j]);
        printf("\n");
    }
}

int MIN(int m,int n)
{
	if(m<=n)
	return m;
	else
	return n;
}

void Dijkstra(MGraph *G)//對給定的有向圖,求從源點1到其餘每個頂點的最短路經長度 
{
	int i,j,k;
	int choose,counter;
	int S[MAX_V];//儲存頂點點集
	int P[MAX_V];//儲存路徑 
	memset(S,0,MAX_V);
	for(i=0;i<G->v;i++) // 
      P[i]=0;
	
	int D[MAX_V];//儲存從源點到其餘各頂點的最短路徑距離 
	S[0]=1;//初始化第一個結點
	D[0]=0;//源點到源點距離為0 
	   
	for(i=1;i<G->v;i++) //初始化D 
      D[i]=G->weight[0][i];
    D[G->v]=INF;
    
	cout << "初始化單源最短路徑" <<endl; 
	for(i=0;i<G->v;i++) // 
      printf("%5d\n",D[i]);
    printf("\n");
    
	for(i=1;i<=G->v-1;i++)
	{
		choose = D[G->v];
		for(j=1;j<G->v;j++)//尋找最短路徑V-S 
		{
			if((S[j]!=1)&&(choose>D[j]))
			{
			  choose = D[j];
			  counter = j;
			}
		}
		S[counter]=1;//將頂點j加入S中
		 
		for (j=1;j<G->v;j++)
		{
			if(S[j]!=1)
			{
				if(D[counter]+G->weight[counter][j]<D[j])
				  P[j]=counter;
				D[j]=MIN(D[j],D[counter]+G->weight[counter][j]);
				
			}
		}		
	}      
    cout << "各頂點的單源最短路徑" <<endl;
	for(k=1;k<G->v;k++) // 
      printf("%5d\n",D[k]);
      
    cout <<endl;
    
	cout << "回退矩陣"<<endl; 
	for(k=0;k<G->v;k++) // 
      printf("%5d\n",P[k]);
    
    cout << "輸入最短路徑點:"<< endl;
	cin >> i ;
	printf("%d ",i);
	while(P[i]!=0) 
	{
		printf("%d ",P[i]);
		i = P[i];
	}
	printf("0");

}
int main()
{
	struct MGraph *G;
	G = new MGraph;
	CreateMGragh(G);
	cout << "顯示鄰接矩陣" <<endl; 
	DisplayMGragh(G);
	cout << "顯示權值矩陣" <<endl; 
	DisplayMGragh_W(G);
	Dijkstra(G);
	delete G;
	return 0;
}