poj 1258 MST模板题(用PRIM+堆实现)

来源:互联网 发布:单片机485接口电路 编辑:程序博客网 时间:2024/05/16 05:16

题意:求图的MST。

思路:PRIM算法,其中找最小边用priority_queue实现。注意不加堆的Prim 算法适用于密集图(O(V^2)),加堆的适用于稀疏图O(ElogV)。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <cstdlib>using namespace std;#define N 105struct edge{    int x,y,next,w;    bool operator<(const struct edge &b)const{        return w>b.w;    }}e[N*N*2];int first[N],top,n,used[N];priority_queue<struct edge> h;void add(int x,int y,int w){    e[top].x = x;    e[top].w = w;    e[top].y = y;    e[top].next = first[x];    first[x] = top++;}int prim(){    int i,j,res=0;    used[1] = 1;//点1作为第一个加入的点    for(i = first[1];i!=-1;i=e[i].next)        h.push(e[i]);    for(i = 1;i<n;){        struct edge now = h.top();        h.pop();        if(used[now.y])//如果这条边的两个端点已经加入了,那么这条边不能用            continue;        used[now.y] = 1;        res += now.w;        for(j = first[now.y];j!=-1;j=e[j].next)//这个地方也可以像不加堆写法那样弄一个dis数组,对未加入MST的点仅当其邻接的最小边更新时才加入            if(!used[e[j].y])                h.push(e[j]);        i++;    }    return res;}int main(){    while(scanf("%d",&n)!=EOF){        int i,j,w;        top = 0;        while(!h.empty())            h.pop();        memset(first, -1, sizeof(first));        memset(used, 0, sizeof(used));        for(i = 1;i<=n;i++)            for(j = 1;j<=n;j++){                scanf("%d",&w);                if(i!=j)                    add(i,j,w);            }        printf("%d\n",prim());    }    return 0;}


0 0
原创粉丝点击