图的Prim,Kruskal,Dijkstra,Floyd算法
Posted cimuhuashuimu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的Prim,Kruskal,Dijkstra,Floyd算法相关的知识,希望对你有一定的参考价值。
代码部分有点问题,具体算法没问题,
最近期末考,要过段时间才会修改
//邻接矩阵,具体情况看上一篇的图的实现
template<class T>
class MGraph {
public:
MGraph(T a[], int n, int e);
void DFS(int v);
void BFS(int v);
private: //edge为边用来表示无向图,arc为弧用来表示有向图,vertex为顶点
T vertex[MAXSIZE];
int arc[MAXSIZE][MAXSIZE];
int edge[MAXSIZE][MAXSIZE];
int vNum, arcNum,eNum;
bool* visited; //DFS使用
};
//生成最小生成树的算法,这里存储结构全部使用邻接矩阵
//Prim算法
template<class T>
void Prim(MGraph<T> G) {
int adjvex[MAXSIZE];
int lowcost[MAXSIZE];
int k = 0;
for (int i = 0; i < G.vNum; i++) {
adjvex[i] = 0;
lowcost[i] = G.arc[0][i];
}
lowcost[k] = 0;
for (int i = 1; i < G.vNum; i++) {
k = mininum(G, lowcost);
cout << "V" << adjvex[k] << "->V" << k << endl;
lowcost[k] = 0;
for (int j = 0; j < G.vNum; j++) {
if (lowcost[j] != 0 && G.arcs[k][j] < lowcost[j]) {
lowcost[j] = G.arc[k][j];
adjvex[j] = k;
}
}
}
}
//Kruskal算法
struct VEdge {
int fromV;
int endV;
int weight;
};
template<class T>
void GenSortEdge(MGraph<T> G, VEdge EdgeList[]) {
int k = 0, i, j;
for (i = 0; i < G.vNum; i++) {
for (j = i; j < G.vNum; j++) {
if (G.arc[i][j] != MAX) {
EdgeList[k].fromV = i;
EdgeList[k].endV = j;
EdgeList[k].weight = G.arc[i][j];
k++;
}
}
}
for (i = 0; i < G.e - 1; j++) {
for (j = i + 1; j < G.e; j++) {
if (EdgeList[i].weight > EdgeList[j].weight) {
VEdge t = EdgeList[i];
EdgeList[i] = EdgeList[j];
EdgeList[j] = t;
}
}
}
}
template<class T>
void Kruskal(VEdge EdgeList[], int n, int e) {
int vset[MAX_VERTEX];
for (int i = 0; i < n; i++) {
vset[i] = i;
}
int k = 0, j = 0;
while (k < n - 1) {
int m = EdgeList[j].fromV, n = EdgeList[j].endV;
int sn1 = vset[m];
int sn2 = vset[n];
if (sn1 != sn2) {
cout << "V" << m << "->V" << n << endl;
k++;
for (i = 0; i < n; i++) {
if (vset[i] == sn2) {
vset[i] = sn1;
}
}
}
j++;
}
}
//最短路径算法,存储结构为邻接矩阵为例
//Dijkstra算法
template<class T>
void ShortPath(MGraph<T> G, int v, int Disk[], char P[]) {
bool S[MAX_VALUE];
for (int i = 0; i < G.vNum; i++) {
S[i] = false;
Disk[i] = G.arc[v][i];
if (Disk[i] != MAX) {
Path[i] = v;
}
else {
Path[i] = -1;
}
}
S[v] = true;
Disk[v] = 0;
for (int i = 0; i < G.vNum; i++) {
if (v = FindMin(Disk, S, G.n) == -1) {
return;
}
S[v] = true;
for (int j = 0; j < G.vNum; j++) {
if (!S[j] && Disk[j] > G.arc[v][j] + Disk[v]) {
Disk[j] = G.arc[v][j] + Disk[v];
Path[j] = path[k] + G.vertex[j];
}
}
}
Print(Disk, Path, G.n);
}
int FindMin(int D[], int S[], int n) {
int k = 0, min = MAX;
for (int i = 0; i < n; i++) {
if (!S[i] && min > D[i]) {
min = D[i];
k = i;
}
}
if (min == MAX) {
return -1;
}
return k;
}
void Print(int D[], int P[], int n) {
for (int i = 0; i < n; i++) {
cout << "V" << i << ":" << D[i] << " {V" << i;
int pre = P[i];
while (pre != -1) {
cout << "V" << pre;
pre = P[pre];
}
cout << "}" << endl;
}
}
//Floyd算法
template<class T>
void Floyd(MGraph<T> G) {
for (int i = 0; i < G.vNum; i++) {
for (int j = 0; j < G.vNum; j++) {
dist[i][j] = G.arc[i][j];
if (dist[i][j] != MAX_VALUE) {
path[i][j] = G.vertex[i]+G.vertex[j];
}
else {
path[i][j] = "";
}
}
}
for (int k = 0; k < G.vNum; i++) {
for (int i = 0; i < G.vNum; j++) {
for (int j = 0; j < G.vNum; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = path[i][k] + path[k][j];
}
}
}
}
}
以上是关于图的Prim,Kruskal,Dijkstra,Floyd算法的主要内容,如果未能解决你的问题,请参考以下文章
最小生成树(Prim,Kruskal)--最短路径(Dijkstra,Floyd)算法详解