把链式图和矩阵图的Dijkstra写了一下。矩阵图用二维数组保存的,链式图用一维vector数组保存的。
#include <bits/stdc++.h>
#define INF 99999999
using namespace std;
/*
过程变量:
int length; //原点到顶点的最短路径
int visit; //标记顶点,分成两个集合
*/
/*
算法思路:
假设两个集合,起点s,终点v。一个集合保存已知最短路径的顶点(S),初始为空;一个保存不知
最短路径的顶点(T),初始为全集。实际操作时采取设标识符的方法。首先把 s加入S,然后每次
向外搜索最短路径时把此时距s最近的顶点加入S,加入后更新length,直到加入的是v;
*/
/*
伪码:
初始化 s的过程变量
循环vertexNum次:
求出当前最短路径对应的顶点
如果是v,则退出
循环vertexNum次:
更新过程变量
*/
/*
拓展:
1)求点到顶点的最短路径个数
2)求点到顶点走过的路径
3)最短路径是边权最小,若在边权最小时还需要点权最小,可以补充边权
*/
/*
补充过程变量:
int num; //原点到顶点的路径个数
vector<int> pre; //原点到顶点走过的路径
int weight; //原点到顶点的另一标准:点权
*/
class Help
{
public:
int visit, length, num;
vector<int> pre;
Help(){ visit = 0; num = 1; length = INF; }
};
class MGraph //矩阵图
{
public:
int n;
int **matrix;
MGraph(){ matrix = NULL; }
};
class Node //链式图
{
public:
int n;
int ew;
Node(int tn, int tw){ n = tn; ew = tw; }
};
class LGraph
{
public:
vector<Node> *vs;
int n;
LGraph(){ vs = NULL; }
};
MGraph* create_mGraph()
{
int i, from, to, w, vn, en; //点数、边数
MGraph *g = new MGraph();
scanf("%d%d", &vn, &en);
g->n = vn;
g->matrix = new int*[vn];
for(i = 0; i < vn; i++)
{
g->matrix[i] = new int[vn];
fill(g->matrix[i], g->matrix[i] + vn, INF);
g->matrix[i][i] = 0;
}
for(i = 0; i < en; i++)
{
cin >> from >> to >> w;
g->matrix[from][to] = w;
//无向图修改成: g->matrix[from][to] = g->matrix[to][from] = w;
}
return g;
}
LGraph *create_lGraph()
{
int i, from, to, w, vn, en; //点数、边数
LGraph *g = new LGraph();
scanf("%d%d", &vn, &en);
g->n = vn;
g->vs = new vector<Node>[vn];
for(i = 0; i < en; i++)
{
cin >> from >> to >> w;
Node *temp = new Node(to, w);
g->vs[from].push_back(*temp);
//无向图加上:Node temp(from, w); g->vs[to].push_back(temp);
}
return g;
}
//矩阵图的dijkstra算法实现
Help *dijkstra_mGraph(int s, int v, MGraph *g)
{
int i, j, vn = g->n;
Help *h = new Help[vn];
h[s].length = 0;
for(i = 0; i < vn; i++)
{
int cur = -1, min = INF;
for(j = 0; j < vn; j++) //时间复杂度vn的平方
if(h[j].length < min && !h[j].visit)
min = h[cur = j].length;
if(cur == v) //如果需要判断是否有路,在这步之前判断
return h;
h[cur].visit = 1;
for(j = 0; j < vn; j++)
{
if(!h[j].visit && g->matrix[cur][j] != INF)
{
int newLen = g->matrix[cur][j] + h[cur].length;
if(newLen < h[j].length)
{
h[j].length = newLen;
h[j].pre.clear();
h[j].pre.push_back(cur);
h[j].num = h[cur].num;
}else if(newLen == h[j].length){
h[j].pre.push_back(cur);
h[j].num += h[cur].num;
}
}
}
}
}
//链式图的dijkstra算法实现
Help *dijkstra_lGraph(int s, int v, LGraph *g)
{
int i, j, vn = g->n;
Help *h = new Help[vn];
h[s].length = 0;
for(i = 0; i < vn; i++)
{
int min = INF, cur = -1;
for(j = 0; j < vn; j++)
if(h[j].length < min && !h[j].visit)
min = h[cur = j].length;
h[cur].visit = 1;
if(cur == v)
return h;
for(j = 0; j < g->vs[cur].size(); j++)
{
Node to = g->vs[cur][j];
int newLen = h[cur].length + to.ew;
if(newLen < h[to.n].length)
{
h[to.n].length = newLen;
h[to.n].num = h[cur].num;
h[to.n].pre.clear();
h[to.n].pre.push_back(cur);
}else if(newLen == h[to.n].length){
h[to.n].pre.push_back(cur);
h[to.n].num += h[cur].num;
}
}
}
}
int main()
{
int s, v;
//链式图
LGraph *lg = create_lGraph();
for(int i = 0; i < lg->n; i++)
{
cout << i << " ";
for(int j = 0; j < lg->vs[i].size(); j++)
cout << lg->vs[i][j].n << " ";
cout << endl;
}
cin >> s >> v;
Help *lh = dijkstra_lGraph(s, v, lg);
//矩阵图
MGraph *mg = create_mGraph();
for(int i = 0; i < mg->n; i++)
{
for(int j = 0; j < mg->n; j++)
cout << mg->matrix[i][j] << " ";
cout << endl;
}
cin >> s >> v;
Help *mh = dijkstra_mGraph(s, v, mg);
return 0;
}
/*
graph:
5 8
0 1 10
0 3 30
0 4 100
1 2 50
2 4 10
3 1 10
3 2 20
3 4 60
s、v:
0 4
dijkstra:
0 INF INF INF INF
0 10 INF 30 100
0 10 60 30 100
0 10 50 30 90
0 10 50 30 60
*/