hiho 26 最小生成树 prime

问题描述

http://hihocoder.com/problemset/problem/1097?sid=773144

算法描述

首先我想证明一个结论:对于城市i(i≠1),如果i与城市1的距离不超过其他任何城市j(j≠1)与城市1的距离,那么(1, i)这一条边一定存在于某一棵最小生成树中。”

使用这个结论,我们可以得到prime算法。
如果我确定了(1, i)这条边一定存在于某一棵最小生成树中,那么我仿照Dijstra算法的思想,将1和i合并为一个点,那么问题是不是就变成了求剩下的N-2个点和这个点的最小生成树。

这里注意,在实现时维护一个当前树到未加入树的节点之间最小距离。不能每次重新算,否则会是O( n3 )复杂度。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
enum {maxn = 1024};
int G[maxn][maxn];
int N;
int all = 0;
bool chose[maxn];
vector<int> treeNode;
int main()
{
    //freopen("in.txt", "r", stdin);
    memset(chose, 0, sizeof(chose));
    scanf("%d", &N);
    for (int i=0; i< N; i++)
        for (int j = 0; j<N; j++)
            scanf("%d", &G[i][j]);
    chose[0] = true;
    all = 0;
    //treeNode.push_back(0);

    // O(N^3) TLE
   /* for (int i=1; i< N; i++)
    {
        int Min = 1<<30;
        int MinNode = -1;
        for (int j=0; j<treeNode.size(); j++ )
        {
            int node = treeNode[j];
            for (int k=0; k< N; k++)
                if (!chose[k] && G[node][k] < Min)
                 {
                     Min = G[node][k];
                     MinNode = k;
                 }
        }
        treeNode.push_back(MinNode);
        chose[MinNode] = true;
        all += Min;
    }*/
    // O(N^2);
    int s = 0;
    for (int i=1; i< N; i++)
    {
        int t= -1;
        for (int j=0; j<N; j++ )
        {
            if (!chose[j]){
                if (G[s][j] < G[0][j]) G[0][j] = G[s][j];
                if (t<0 || G[0][t] > G[0][j]) t = j;
            }
        }
        s = t;
        chose[t] = true;
        all += G[0][s];
    }
    printf("%d\n", all);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值