1. 程式人生 > >第4章 貪心演算法,Dijkstra演算法(鄰接矩陣儲存,時間複雜度為O(n^2))

第4章 貪心演算法,Dijkstra演算法(鄰接矩陣儲存,時間複雜度為O(n^2))

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define MAXSIZE 100
#define INF 999999999

int weight[MAXSIZE][MAXSIZE];	//邊的權值
int shortest[MAXSIZE];			//源點到每個點的最短路徑長度
bool vis[MAXSIZE];				//頂點訪問標記
int preV[MAXSIZE];				//最短路徑

int Dijkstra(int n, int src, int dest)
{
	memset(vis, false, sizeof(vis));
	int i;
	for (i = 1; i <= n; i++)
	{
		shortest[i] = INF;
	}
	shortest[src] = 0;
	preV[src] = 0;

	for (i = 1; i <= n; i++)
	{
		int minV = INF;
		int x, y;
		//挑選出未訪問且路徑長度最短的頂點
		for (y = 1; y <= n; y++)
		{
			if (!vis[y] && shortest[y] < minV)
			{
				minV = shortest[x = y];
			}
		}
		vis[x] = true;	//該頂點標記為已訪問
		
		for (y = 1; y <= n; y++)
		{
			//經過x頂點到y頂點是否路徑更短
			if (shortest[x]+weight[x][y] < shortest[y])
			{
				shortest[y] = shortest[x]+weight[x][y];
				preV[y] = x;	//到y的最短路徑上,y的前一個頂點為x
			}
		}
	}
	return shortest[dest];
}

void InitGraph(int n)
{
	int i, j;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			weight[i][j] = INF;
		}
	}
}

int main(void)
{
	int n, m;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		InitGraph(n);
		int i;
		for (i = 0; i < m; i++)
		{
			int v1, v2, w;
			scanf("%d%d%d", &v1, &v2, &w);
			weight[v1][v2] = weight[v2][v1] = w;
		}
		int src, dest;
		scanf("%d%d", &src, &dest);

		printf("%d\n", Dijkstra(n, src, dest));
		for (i = dest; i != 0; i = preV[i])
		{
			printf("%d ", i);
		}
		putchar('\n');
	}
	return 0;
}

/*
7 12
1 2 2
1 3 5
1 4 7
2 3 4
2 5 7
3 4 1
3 5 9
3 6 6
4 6 3
5 6 2
5 7 5
6 7 4
*/