最小生成树(MST)Prim算法 贪心算法

注意:建立邻边矩阵时,注意它的无方向

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<memory.h>
#include<cstdio>
#include<list>
#include<string>
#include<map>
#include<cmath>
#include <algorithm>
#include <queue>

#define NUM 100
#define maxint 10000000
#define INF 0x3f3f3f3f
using namespace std;

int c[NUM][NUM];//用邻接矩阵存储边和权
int dist[NUM];

int prim(int c[][NUM],int num)
{
    int sum = 0;
    set<int> S,T;
    set<int>::iterator pos1;
    set<int>::iterator pos2;
    S.insert(1);
    for(int i = 2;i<=num;i++)
    {
        T.insert(i);
    }
    
    while (S.size()!=num) {
        
        int min_num = maxint;
        set<int>::iterator pos1_copy;
        set<int>::iterator pos2_copy;
        for(pos1 = S.begin();pos1!=S.end();pos1++)
        {
            int s_num = *pos1;
            for(pos2 = T.begin();pos2!=T.end();pos2++)
            {
                int t_num = *pos2;
                if( (c[s_num][t_num]< maxint) && (min_num>c[s_num][t_num] )  )
                {
                    min_num = c[s_num][t_num];
                    pos2_copy = pos2;
                    pos1_copy = pos1;
                }
            }
        }
        sum += min_num;
        S.insert(*pos2_copy);
        T.erase(pos2_copy);
        cout<<*pos1_copy<<"  "<<*pos2_copy<<endl;
        

    }
    cout<<endl;
    
    
    return sum;
}


int main()
{
    freopen("in.txt", "r", stdin);
    int v_num,e_num;
    while(cin>>v_num>>e_num && (v_num || e_num))
    {
        memset(c,1,sizeof c);
        for(int i = 1;i<=e_num;i++)
        {
            int x, y , weight;
            cin>>x>>y>>weight;
            c[x][y] = weight;
            c[y][x] = weight;
        }
        prim(c,v_num);
        
    }
        

//    map<string , int> map1;
//    map<string , int>::iterator pos;
//    map1["zhu"] = 5;
//    map1["jia"] = 3;
//    map1["ning"] = 4;
//    map1["ning"] = 2;
//    map1["jia"] = 6;
//    for(pos = map1.begin();pos!=map1.end();pos++)
//    {
//        cout<<pos->first<<" ";
//        cout<<pos->second<<endl;
//    }
//    cout<<map1.count("jia1")<<endl;;
//    cout<<map1["sf"]<<endl;
//    cout<<map1.size()<<endl;
//    map1.erase("ning");
//    for(pos = map1.begin();pos!=map1.end();pos++)
//    {
//        cout<<pos->first<<" ";
//        cout<<pos->second<<endl;
//    }
    
}



输入:

6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
5 7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
6 14
1 4 50
2 3 94
2 5 96
3 1 98
4 1 17
4 5 87
4 1 6
5 2 89
5 6 83
6 4 56
6 1 35
6 2 15
6 5 2
6 4 17
6 14
1 4 50
2 3 94
2 5 96
3 1 98
4 1 17
4 5 87
4 1 6
5 2 89
5 6 83
6 4 56
6 1 35
6 2 15
6 5 2
6 4 17
7 9
1 4 38
2 7 35
3 1 57
3 2 94
4 3 77
5 6 6
6 5 63
6 5 49
7 6 82
4 5
1 3 74
2 4 41
3 2 14
4 3 76
4 1 73
6 13
1 2 55
1 6 99
1 6 47
2 4 15
2 3 47
2 5 89
2 5 70
3 6 39
4 3 64
4 5 76
5 2 16
5 2 22
6 3 76
5 8
1 2 27
1 3 79
1 5 51
2 1 2
3 4 62
4 2 100
4 3 56
5 1 64
10 21
1 3 53
2 4 72
2 9 69
3 4 94
3 5 86
3 9 38
3 4 12
4 2 5
4 6 78
4 7 7
4 10 69
4 6 23
5 8 14
6 3 1
7 10 43
8 5 38
9 3 39
9 6 89
10 2 56
10 9 90
10 3 48
5 7
1 4 5
2 4 63
2 1 4
2 3 3
3 2 70
4 5 55
5 3 30
4 5
1 4 63
2 4 21
3 2 71
3 1 23
4 3 74
5 10
1 3 8
1 2 96
1 2 29
1 3 82
2 1 91
3 5 11
4 5 78
4 1 72
4 3 37
5 4 60
9 18
1 8 18
2 8 72
3 1 61
4 5 53
4 2 59
5 8 34
5 1 56
5 9 66
6 7 27
6 1 2
6 1 35
7 4 60
7 6 94
8 7 49
8 3 74
9 5 93
9 1 94
9 7 34
5 8
1 3 61
1 5 94
2 3 73
2 3 3
3 4 77
3 4 44
4 3 74
5 2 67
5 8
1 2 41
1 2 84
2 1 63
2 3 10
3 5 8
4 2 39
5 4 61
5 3 72
6 9
1 2 24
2 3 65
2 6 75
2 6 47
3 5 38
4 1 82
5 3 19
6 4 12
6 5 93
5 7
1 4 42
2 1 37
3 4 68
4 5 29
4 2 54
5 4 10
5 3 74
5 8
1 5 39
1 2 72
2 5 48
3 4 16
3 5 93
3 4 12
4 5 58
5 3 6
6 7
1 6 29
2 3 68
3 5 52
3 4 20
4 2 92
5 3 67
6 4 18
10 21
1 5 69
1 10 28
2 1 49
2 5 94
2 10 83
2 4 72
2 8 70
3 9 94
4 8 78
4 5 15
4 5 5
5 10 85
5 6 44
6 7 96
7 10 12
8 9 94
9 3 93
9 2 99
9 4 91
10 2 100
10 6 91
7 16
1 6 24
1 7 19
1 5 51
2 3 98
2 4 37
3 7 92
3 5 7
3 1 11
4 3 14
5 2 52
5 4 81
5 3 45
5 4 44
5 6 42
6 3 46
7 6 79
0 0


输出:

1  3
3  6
6  4
3  2
2  5

1  2
1  4
4  3
3  5

1  4
4  6
6  5
6  2
2  3

1  4
4  6
6  5
6  2
2  3

1  4
1  3
3  2
2  7
7  6
6  5

1  4
4  2
2  3

1  6
1  2
2  4
2  5
2  3

1  2
1  5
1  3
3  4

1  3
3  6
3  4
4  2
4  7
3  9
7  10
3  5
5  8

1  2
1  4
4  5
5  3

1  3
1  4
4  2

1  4
4  3
3  5
1  2

1  8
8  5
1  6
8  7
7  9
5  4
4  2
1  3

1  3
3  2
2  5
3  4

1  2
2  3
2  4
4  5

1  2
2  6
6  4
2  3
3  5

1  2
1  4
4  5
4  3

1  5
5  3
3  4
5  2

1  6
6  4
4  3
3  5
3  2

1  10
10  7
1  2
1  5
5  4
5  6
2  8
4  9
9  3

1  3
3  4
1  7
1  6
4  2
6  5

另一种解法:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<memory.h>
#include<cstdio>
#include<list>
#include<string>
#include<map>
#include<cmath>
#include <algorithm>
#include <queue>

#define NUM 1000
#define maxint 10000000
#define INF 0x3f3f3f3f
using namespace std;

int c[NUM][NUM];//用邻接矩阵存储边和权
int dist[NUM];

void Prim(int n,int c[][NUM])
{
    int lowcost[NUM];
    int closest[NUM];//与s集合中点的最小距离。
    
    bool s[NUM] = {false};
    
    for(int i = 1;i<=n;i++)
    {
        lowcost[i] = c[1][i];
        closest[i] = 1;
        s[i] = false;
    }
    
    s[1] = true;
    for(int i= 1;i<n;i++)
    {
        int min = maxint;
        int j = 1;
        for(int k = 2;k<=n;k++)
        {
            if( ( lowcost[k]<min ) && (!s[k]) )
            {
                min = lowcost[k];
                j = k;
            }
        }
        s[j] = true;
        printf("%d %d\n",closest[j] ,j);
        for(int k= 2;k<=n;k++)
        {
            if((!s[k] ) && (c[j][k] < lowcost[k]) )
            {
                lowcost[k] = c[j][k];
                closest[k] = j;
            }
        }
    }
    cout<<endl;
    
}

int main()
{
    freopen("in.txt", "r", stdin);
    int v_num,e_num;
    while(cin>>v_num>>e_num && (v_num || e_num))
    {
        for(int i = 1;i<=e_num;i++)
        {
            for(int j = 1;j<=e_num;j++)
            {
                c[i][j] = maxint;
            }
        }
        for(int i = 1;i<=e_num;i++)
        {
            int x, y , weight;
            cin>>x>>y>>weight;
            c[x][y] = weight;
            c[y][x] = weight;
        }
        Prim(v_num,c);
        
    }
        

//    map<string , int> map1;
//    map<string , int>::iterator pos;
//    map1["zhu"] = 5;
//    map1["jia"] = 3;
//    map1["ning"] = 4;
//    map1["ning"] = 2;
//    map1["jia"] = 6;
//    for(pos = map1.begin();pos!=map1.end();pos++)
//    {
//        cout<<pos->first<<" ";
//        cout<<pos->second<<endl;
//    }
//    cout<<map1.count("jia1")<<endl;;
//    cout<<map1["sf"]<<endl;
//    cout<<map1.size()<<endl;
//    map1.erase("ning");
//    for(pos = map1.begin();pos!=map1.end();pos++)
//    {
//        cout<<pos->first<<" ";
//        cout<<pos->second<<endl;
//    }
    
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值