hiho 26 最小生成树 prime

来源:互联网 发布:ps软件羽化是什么意思 编辑:程序博客网 时间:2024/05/17 08:23

问题描述

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;}
0 0
原创粉丝点击