图的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 spfa prim kruskal 总结

23最小生成树之Kruskal算法

最小生成树(Prim,Kruskal)--最短路径(Dijkstra,Floyd)算法详解

最小生成树(Prim,Kruskal)--最短路径(Dijkstra,Floyd)算法详解

最小生成树(Prim,Kruskal)--最短路径(Dijkstra,Floyd)算法详解