Prim算法

Concrete Content

最小生成树的Prim算法也是贪心算法的一大经典应用。Prim算法的特点是时刻维护一棵树,算法不断加边,加的过程始终是一棵树。

Prim算法过程:

一条边一条边地加, 维护一棵树。
初始 E = { } E ={} E空集合, V = { V = { V=任意节点 } }
循环 ( n – 1 ) (n – 1) n1 次,每次选择一条边 ( v 1 , v 2 ) (v1,v2) v1,v2, 满足: v 1 v1 v1 属于 V , v 2 V , v2 V,v2 不属于 V V V。且 ( v 1 , v 2 ) (v1,v2) v1,v2权值最小。
E = E + ( v 1 , v 2 ) E = E + (v1,v2) E=E+v1,v2
V = V + v 2 V = V + v2 V=V+v2
最终 E E E 中的边是一棵最小生成树, V V V 包含了全部节点。
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法;

输入

第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。 ( 2 < = N < = 1000 , 1 < = M < = 50000 ) (2 <= N <= 1000, 1 <= M <= 50000) 2<=N<=1000,1<=M<=50000)
2 − M + 1 2 - M + 1 2M+1行:每行3个数 S S S E E E W W W,分别表示M条边的2个顶点及权值。 ( 1 < = S , E < = N , 1 < = W < = 10000 ) (1 <= S, E <= N,1 <= W <= 10000) (1<=S,E<=N1<=W<=10000)

输出

输出最小生成树的所有边的权值之和。

输入示例

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

输出示例

37

请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。

代码如下:
? (☄⊙ω⊙)☄

#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int maxx=1100;
int e[maxx][maxx],dis[maxx];
bool book[maxx];
int n,m;
void init()
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(i==j)e[i][j]=0;
            else
                e[i][j]=inf;
}
int prim(int e[][maxx],int n)
{
    int ans=0;
    memset(book,false,sizeof(book));
    book[0]=true;
    for(int i=1; i<n; i++)
        dis[i]=e[0][i];
    for(int i=1; i<n; i++)
    {
        int minn=inf,u=-1;
        for(int j=0; j<n; j++)
        {
            if(!book[j]&&dis[j]<minn)
            {
                minn=dis[j];
                u=j;
            }
        }
        if(ans==inf)
            return -1;
        ans+=minn;
        book[u]=true;
        for(int v=0; v<n; v++)
            if(!book[v])
                dis[v]=min(dis[v],e[u][v]);
    }
    return ans;
}
int main()
{
    while(cin>>m>>n)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            if(e[a-1][b-1]>c)
                e[a-1][b-1]=e[b-1][a-1]=c;
        }
        cout<<prim(e,m)<<endl;
    }
    return 0;
}

以下图为例介绍Prim算法的执行过程。
Prim算法_第1张图片
Prim算法的过程从A开始 V = {A}, E = {}
Prim算法_第2张图片
选中边AF , V = {A, F}, E = {(A,F)}
Prim算法_第3张图片
选中边FB, V = {A, F, B}, E = {(A,F), (F,B)}
Prim算法_第4张图片
选中边BD, V = {A, B, F, D}, E = {(A,F), (F,B), (B,D)}
Prim算法_第5张图片
选中边DE, V = {A, B, F, D, E}, E = {(A,F), (F,B), (B,D), (D,E)}
Prim算法_第6张图片
选中边BC, V = {A, B, F, D, E, c}, E = {(A,F), (F,B), (B,D), (D,E), (B,C)}, 算法结束。

你可能感兴趣的:(图片解说,Prim算法)