//
// main.cpp
// testcpp
//
// Created by 222 on 16/9/16.
// Copyright © 2016年 222. All rights reserved.
//
#include <iostream>
#include <stack>
using namespace std;
const int maxnum = 100;//顶点个数
const int maxint = 999999;//表示不可达
void Dijkstra(int n, int v_beg, int *dist, int *prev, int c[maxnum][maxnum]){
//初始化
bool used[maxint];
for(int i = 1; i <= n; ++i){
used[i] = false;
dist[i] = c[v_beg][i];
if (maxint == dist[i]) {
prev[i] = -1;
}else{
prev[i] = v_beg;
}
}
prev[v_beg] = -1;//将源点置-1,方便搜索路径时作为结束标志
used[v_beg] = true;
// 依次将未放入used集合的结点中:取dist[]最小值的结点,放入结合S中
// 循环完成后used包含了所有V中顶点,dist记录了从源点到所有其他顶点之间的最短路径长度
// prev[]记录了每个点的前驱,根据这个找到路径的逆序
for(int cnt = 2; cnt <= n; ++cnt){
int curMin = maxint;
int idx = -1;
for (int i = 1; i <= n; ++i) {//寻找不在used中且距离最小的一个
if (!used[i] && (dist[i] < curMin)) {
curMin = dist[i];
idx = i;
}
}
used[idx] = true;//找到不在used中且距离最小的一个,加入used[]
//更新dist[]和prev[]
for (int i = 0; i <= n; ++i) {
if (!used[i]) {
int tmp_dist = dist[idx] + c[idx][i];
if ( tmp_dist < dist[i]) {
dist[i] = tmp_dist;
prev[i] = idx;
}
}
}
}
}
//找到源点到e点的路径
void searchPath(int *prev, int v_beg, int e){
stack<int> stk;
int idx = e;
stk.push(idx);
while (-1 != prev[idx]) {
stk.push(prev[idx]);
idx = prev[idx];
}
while (!stk.empty()) {
int v = stk.top();
if (v != e) {
cout << stk.top() << "->";
}else{
cout << stk.top() << endl;
}
stk.pop();
}
}
int main(int argc, const char * argv[]) {
int n,line;//顶点数,边数
int c[maxnum][maxnum];
int prev[n+1];
int dist[n+1];
cout << "输入顶点数、边数:" << endl;
cin >> n >> line;
//先全部初始化为最大距离
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
c[i][j] = maxint;
}
}
cout << "依次输入两顶点和两点距离:" << endl;
int p, q, dst;//两顶点
for (int i = 1; i <= line; ++i) {
cin >> p >> q >> dst;
c[p][q] = dst;
c[q][p] = dst;//无向图
}
Dijkstra(n, 1, dist, prev, c);
//找到源点到最后一个点的距离
searchPath(prev, 1, n);
cout << "min dist: " << dist[n] << endl;
return 0;
}
//
// main.cpp
// testcpp
//
// Created by 222 on 16/9/16.
// Copyright © 2016年 222. All rights reserved.
//
#include <iostream>
#include <stack>
using namespace std;
const int maxnum = 100;//顶点个数
const int maxint = 999999;//表示不可达
//-----------------------------------------
//Floyd
//-----------------------------------------
void Floyd(int n, int c[maxnum][maxnum], int path[maxnum][maxnum]){
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
path[i][j] = -1;
}
}
for (int k = 1; k <= n; ++k) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (c[i][j] > c[i][k] + c[k][j]) {
c[i][j] = c[i][k] + c[k][j];
path[i][j] = k;
}
}
}
}
}
void searchPath_Floyd (int path[maxnum][maxnum], int n, int m) {
stack<int> stk;
int idx = m;
stk.push(idx);
while (-1 != path[n][idx]) {
stk.push(path[n][idx]);
idx = path[n][idx];
}
stk.push(n);
while (!stk.empty()) {
int v = stk.top();
if (v != m) {
cout << stk.top() << "->";
}else {
cout << stk.top() << endl;
}
stk.pop();
}
}
int main(int argc, const char * argv[]) {
//Floyd
int n,line;//顶点数,边数
int c[maxnum][maxnum];
int path[maxnum][maxnum];
cout << "输入顶点数、边数:" << endl;
cin >> n >> line;
//先全部初始化为最大距离
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
c[i][j] = maxint;
}
c[i][i] = 0;
}
cout << "依次输入两顶点和两点距离:" << endl;
int p, q, dst;//两顶点
for (int i = 1; i <= line; ++i) {
cin >> p >> q >> dst;
c[p][q] = dst;
//c[q][p] = dst;//无向图
}
Floyd(n, c, path);
cout << "所有i-j最短距离矩阵:" << endl;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
printf("%6d", c[i][j]);
}
cout << endl;
}
cout << "路径:" << endl;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
printf("%6d", path[i][j]);
}
cout << endl;
}
cout << "例如:1-4 路径: ";
searchPath_Floyd(path, 1, 4);
return 0;
}