/***************************************
* About: 有向图的Dijkstra算法实现
* Author: Tanky Woo
* Blog: www.WuTianQi.com
***************************************/
#include <iostream>
#include <stdio.h>
using namespace std;
const int MAX_NUM = 100;
const int INT_MAX = 999999;
// 各数组都从下标1开始
int min_cost[MAX_NUM]; // 表示当前点到源点的最短路径长度
int prev[MAX_NUM]; // 记录当前点的前一个结点
int cost[MAX_NUM][MAX_NUM]; // 记录图的两点间路径长度
int node_num, line; // 图的结点数和路径数
// node_num -- n nodes
// start_node -- the source node
// min_cost[] -- the min_costance from the ith node to the source node
// prev[] -- the previous node of the ith node
// cost[][] -- every two nodes' min_costance
void Dijkstra(int node_num, int start_node, int *min_cost, int *prev, int cost[MAX_NUM][MAX_NUM])
{
int i, j;
int min;
int next_node;
int min_cost_sum;
bool used[MAX_NUM]; // 判断是否已存入该点到S集合中
for (i = 1; i <= node_num; i++)
{
min_cost[i] = cost[start_node][i];
used[i] = 0; // 初始都未用过该点
if (min_cost[i] == INT_MAX)
{
prev[i] = 0;
}
else
{
prev[i] = start_node;
}
}
min_cost[start_node] = 0;
used[start_node] = 1;
// 依次将未放入used集合的结点中,取min_cost[]最小值的结点,放入结合used中
// 一旦used包含了图中所有顶点,min_cost就记录了从源点到所有其他顶点之间的最短路径长度
// 注意是从第二个节点开始,第一个为源点
for (i = 2; i <= node_num; ++i)
{
min = INT_MAX;
next_node = start_node;
// 找出当前未使用的点j的min_cost[j]最小值
for (j = 1; j <= node_num; j++)
{
if((!used[j]) && (min_cost[j]<min))
{
next_node = j;
min = min_cost[j];
}
}
used[next_node] = 1; // 表示next_node点已存入used集合中
//printf ("%d --> %d cost = %d\n", prev[next_node], next_node, min);
// 更新min_cost
for (j = 1; j <= node_num; j++)
{
if((!used[j]) && cost[next_node][j]<INT_MAX)
{
min_cost_sum = min_cost[next_node] + cost[next_node][j];
if(min_cost_sum < min_cost[j])
{
min_cost[j] = min_cost_sum;
prev[j] = next_node;
}
}
}
}
for (i = 1; i <= node_num; i++)
{
printf ("%d --> %d\n", prev[i], i);
}
}
// 查找从源点v到终点u的路径,并输出
void searchPath(int *prev, int start_node, int dest_node)
{
int route[MAX_NUM];
int i = 1;
int j = 0;
int prev_node = prev[dest_node];
route[i++] = dest_node;
while (prev_node != start_node)
{
route[i++] = prev_node;
prev_node = prev[prev_node];
}
route[i] = start_node;
for (j = i; j >= 1; j--)
{
if(j != 1)
{
cout << j << " " << route[j] << " -> ";
}
else
{
cout << route[j] << endl;
}
}
}
int main()
{
freopen("input.txt", "r", stdin);
// 各数组都从下标1开始
// 输入结点数
cin >> node_num;
// 输入路径数
cin >> line;
int p, q, len; // 输入p, q两点及其路径长度
int start_node;
int end_node;
int i, j;
// 初始化cost[][]为INT_MAX
for (i = 1; i <= node_num; ++i)
{
for (j = 1; j <= node_num; ++j)
{
cost[i][j] = INT_MAX;
}
}
for (i = 1; i <= line; ++i)
{
cin >> p >> q >> len;
if(len < cost[p][q]) // 有重边
{
cost[p][q] = len; // p指向q
cost[q][p] = len; // q指向p,这样表示无向图
}
}
for (i = 1; i <= node_num; ++i)
{
min_cost[i] = INT_MAX;
}
#if 0
for (i = 1; i <= node_num; ++i)
{
for(j=1; j <= node_num; ++j)
{
printf("%8d", cost[i][j]);
}
printf("\n");
}
#endif
start_node = 1;
end_node = node_num;
Dijkstra(node_num, start_node, min_cost, prev, cost);
// 最短路径长度
cout << "源点到最后一个顶点的最短路径长度: " << min_cost[end_node] << endl;
// 路径
cout << "源点到最后一个顶点的路径为: ";
searchPath(prev, start_node, end_node);
}
input.txt
5
7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
* About: 有向图的Dijkstra算法实现
* Author: Tanky Woo
* Blog: www.WuTianQi.com
***************************************/
#include <iostream>
#include <stdio.h>
using namespace std;
const int MAX_NUM = 100;
const int INT_MAX = 999999;
// 各数组都从下标1开始
int min_cost[MAX_NUM]; // 表示当前点到源点的最短路径长度
int prev[MAX_NUM]; // 记录当前点的前一个结点
int cost[MAX_NUM][MAX_NUM]; // 记录图的两点间路径长度
int node_num, line; // 图的结点数和路径数
// node_num -- n nodes
// start_node -- the source node
// min_cost[] -- the min_costance from the ith node to the source node
// prev[] -- the previous node of the ith node
// cost[][] -- every two nodes' min_costance
void Dijkstra(int node_num, int start_node, int *min_cost, int *prev, int cost[MAX_NUM][MAX_NUM])
{
int i, j;
int min;
int next_node;
int min_cost_sum;
bool used[MAX_NUM]; // 判断是否已存入该点到S集合中
for (i = 1; i <= node_num; i++)
{
min_cost[i] = cost[start_node][i];
used[i] = 0; // 初始都未用过该点
if (min_cost[i] == INT_MAX)
{
prev[i] = 0;
}
else
{
prev[i] = start_node;
}
}
min_cost[start_node] = 0;
used[start_node] = 1;
// 依次将未放入used集合的结点中,取min_cost[]最小值的结点,放入结合used中
// 一旦used包含了图中所有顶点,min_cost就记录了从源点到所有其他顶点之间的最短路径长度
// 注意是从第二个节点开始,第一个为源点
for (i = 2; i <= node_num; ++i)
{
min = INT_MAX;
next_node = start_node;
// 找出当前未使用的点j的min_cost[j]最小值
for (j = 1; j <= node_num; j++)
{
if((!used[j]) && (min_cost[j]<min))
{
next_node = j;
min = min_cost[j];
}
}
used[next_node] = 1; // 表示next_node点已存入used集合中
//printf ("%d --> %d cost = %d\n", prev[next_node], next_node, min);
// 更新min_cost
for (j = 1; j <= node_num; j++)
{
if((!used[j]) && cost[next_node][j]<INT_MAX)
{
min_cost_sum = min_cost[next_node] + cost[next_node][j];
if(min_cost_sum < min_cost[j])
{
min_cost[j] = min_cost_sum;
prev[j] = next_node;
}
}
}
}
for (i = 1; i <= node_num; i++)
{
printf ("%d --> %d\n", prev[i], i);
}
}
// 查找从源点v到终点u的路径,并输出
void searchPath(int *prev, int start_node, int dest_node)
{
int route[MAX_NUM];
int i = 1;
int j = 0;
int prev_node = prev[dest_node];
route[i++] = dest_node;
while (prev_node != start_node)
{
route[i++] = prev_node;
prev_node = prev[prev_node];
}
route[i] = start_node;
for (j = i; j >= 1; j--)
{
if(j != 1)
{
cout << j << " " << route[j] << " -> ";
}
else
{
cout << route[j] << endl;
}
}
}
int main()
{
freopen("input.txt", "r", stdin);
// 各数组都从下标1开始
// 输入结点数
cin >> node_num;
// 输入路径数
cin >> line;
int p, q, len; // 输入p, q两点及其路径长度
int start_node;
int end_node;
int i, j;
// 初始化cost[][]为INT_MAX
for (i = 1; i <= node_num; ++i)
{
for (j = 1; j <= node_num; ++j)
{
cost[i][j] = INT_MAX;
}
}
for (i = 1; i <= line; ++i)
{
cin >> p >> q >> len;
if(len < cost[p][q]) // 有重边
{
cost[p][q] = len; // p指向q
cost[q][p] = len; // q指向p,这样表示无向图
}
}
for (i = 1; i <= node_num; ++i)
{
min_cost[i] = INT_MAX;
}
#if 0
for (i = 1; i <= node_num; ++i)
{
for(j=1; j <= node_num; ++j)
{
printf("%8d", cost[i][j]);
}
printf("\n");
}
#endif
start_node = 1;
end_node = node_num;
Dijkstra(node_num, start_node, min_cost, prev, cost);
// 最短路径长度
cout << "源点到最后一个顶点的最短路径长度: " << min_cost[end_node] << endl;
// 路径
cout << "源点到最后一个顶点的路径为: ";
searchPath(prev, start_node, end_node);
}
input.txt
5
7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60