最小生成树

来源:互联网 发布:定位寻人软件 编辑:程序博客网 时间:2024/05/22 02:19

prim算法

对这种有记忆性质的变量(在外面定义,循环时会记录上次的值,类似于全局变量),每次使用都要小心,注意初始化问题!!!

#include <iostream>using namespace std;const int N = 6;/*int e[N][N]={        {0,6,1,5,9999,9999},        {6,0,5,9999,3,9999},        {1,5,0,5,6,4},        {5,9999,5,0,9999,2},        {9999,3,6,9999,0,6},        {9999,9999,4,2,6,0}}*///图,注意此图是无向图,关于对角线对称的。int e[N][N]={        {9999,6,1,5,9999,9999},        {6,9999,5,9999,3,9999},        {1,5,9999,5,6,4},        {5,9999,5,9999,9999,2},        {9999,3,6,9999,9999,6},        {9999,9999,4,2,6,9999}};//图,注意此图是无向图,关于对角线对称的。int dist[N];//各点距离生成树的距离int book[N] = {0};//标记各节点是否选入生成树;int sum = 0;int prim(){    for (int i = 0; i < N; ++i) {       dist[i] = e[0][i];    }    book[0] = 1;    int tmp;    int minIndex;    for (int l = 0; l < N-1; ++l) {        tmp = 99999;//第一次忘了在此处初始化tmp, tmp会记录上次运算的值,不初始化有可能在下面的循环里得不到更新minIndex的值,因此此处需要初始化。        // TODO对这种有记忆性质的变量(在外面定义,循环时会记录上次的值,类似于全局变量),每次使用都要小心,注意初始化问题!!!        for (int j = 0; j < N; ++j) {            if (tmp > dist[j] && !book[j]) {                tmp = dist[j];                minIndex = j;            }        }        book[minIndex] = 1;        sum += dist[minIndex];        for (int k = 0; k < N; ++k) {            if(!book[k]) {//                cout << dist[4] <<" " << e[1][4] <<endl;//开始的时候输入数组输错了,浪费了很多时间,以后拍错先看输入是否正确,然后考虑边界,然后考虑逻辑                if (dist[k] > e[minIndex][k]) dist[k] = e[minIndex][k];            }        }    }    return sum;}int main() {    cout << prim() << endl;    return 0;}

kruskal算法

考虑清楚用并查集的意义何在!!!

#include <iostream>#include <queue>using namespace std;/*6 92 4 113 5 134 6 35 6 42 3 64 5 71 2 13 4 91 3 2*/int sum = 0;//并查集int par[8];//一共6个顶点,第七个顶点是未加入树里,第0个顶点是加入树里的 //第一次这种设计是错的,其实只要par[6]就够了,是判断下一条边加进来会不会成环路,而不是把所有点加进树就行了(有可能不连通)void initSet(){    for (int i = 0; i < 8; ++i) {        par[i] = i;    }}int getPar(int a){    if(par[a] != a){        par[a] = getPar(par[a]);    }    return par[a];}void mergeSet(int a,int b){    par[getPar(a)] = getPar(b);}struct Edge{    int a,b;    int w;    Edge(){}    Edge(int x,int y,int z):a(x),b(y),w(z){}    friend bool operator < (Edge m,Edge n){//从小到大排列!!!        return m.w > n.w;    }};Edge edge[9];//一共9条边priority_queue <Edge> q;int main() {    int m,n,a,b,c;    Edge tmpEdge;    cin >> m >> n;    while (n--){        cin >> tmpEdge.a >> tmpEdge.b >> tmpEdge.w;        q.push(tmpEdge);    }//    cout << q.top().w << endl;    initSet();    /*for (int i = 1; i < 8; ++i) {        par[i] = 7;    }*/ //设计错误!    while (!q.empty()){        tmpEdge = q.top();        q.pop();        if(getPar(tmpEdge.a) != getPar(tmpEdge.b)) {//            mergeSet(tmpEdge.a,0);//此处错了,不是把所有点都放到树中就行了,而要判断所有点都要联通且没有环路!//            mergeSet(tmpEdge.b,0);            mergeSet(tmpEdge.a,tmpEdge.b);            sum += tmpEdge.w;        }    }    cout << sum << endl;    return 0;}
0 0
原创粉丝点击