最小生成树--prim

【问题描述】
给定一个无向图,求在这个图中的最小生成树。
解释:最小生成树是在图中构建一棵树使得所连的边对应的权值最小,并且使所有的点都能互相连通

【问题分析】
prim算法
对于所有的点,类似于dijstra算法,划分在俩个集合之中,一个为该点已经连通,另一个反之。
prim算法采用贪心的策略来解决问题,核心在于每次都采取当任一前的不连通的点到任一当前连通的点的最短路径,这样保证每次都可以保证是最优子结构,从而保证整体正确性。由于最小生成树使n个点相连通,一定需要n-1条边,每次还要枚举最优点,时间复杂度O(n)=n^2

该代码求得的是用n-1条边构成的最大生成树,如果对于最小生成树有困惑的话,可以依据下面的内容自行改正。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int N=1001;
queue<int> q;
int n,m;  bool used[N],conect[N];   long long ans;
int cost[N][N],most[N],close[N];
void read()
{
    int a,b,c,i;
    scanf("%d %d",&n,&m);
    for (i=1;i<=m;i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        cost[a][b]=max(cost[a][b],c);
        cost[b][a]=cost[a][b];
    }
    used[1]=1;
    for (i=1;i<=n;i++)
    {
        most[i]=cost[i][1];
        close[i]=1;
    }
    return;
}
bool bfs()
{
    int i,now=1,head;
    while(!q.empty()) q.pop();
    q.push(1);  conect[1]=1;
    while (!q.empty())
    {
        head=q.front();
        for (i=1;i<=n;i++)
            if (cost[head][i]!=0)
                if (!conect[i])
                {
                    q.push(i);
                    conect[i]=1;
                    now++;
                }
        q.pop();
    }
    if (now==n)
        return 1;
    return 0;
}
void build_tree()
{
    int i,mymin,j,now;
    for (i=1;i<n;i++)
    {
        mymin=0;
        for (j=1;j<=n;j++)
            if (most[j]>mymin)
            if (!used[j])
            {
                mymin=most[j];
                now=j;
            }
        used[now]=1;
        for (j=1;j<=n;j++)
        if (!used[j])
            if (cost[j][now]>most[j])
            {
                most[j]=cost[j][now];
                close[j]=now;
            }
    }
    return;
}
void work()
{
    int i;
    if (!bfs())
    {
        printf("-1");
        return;
    }
    else
    {
        build_tree();
        for (i=2;i<=n;i++)
            ans+=cost[i][close[i]];
        printf("%d",ans);
    }
    return;
}
int main()
{
    freopen("cowtract.in","r",stdin);
    freopen("cowtract.out","w",stdout);
    read();
    work();
    return 0;
}

你可能感兴趣的:(算法,Prim)