堆优化Prim

来源:互联网 发布:局域网控制桌面软件 编辑:程序博客网 时间:2024/06/05 18:32
#include<cstdio>#include<algorithm>#include<cstring>#define maxn 5005using namespace std;int n,m,cst[maxn];struct node{    int to,nxt,w;}e[400005];int fir[maxn],cnt_e;void Node(int u,int v,int w){    e[++cnt_e]=(node){v,fir[u],w},fir[u]=cnt_e;    e[++cnt_e]=(node){u,fir[v],w},fir[v]=cnt_e;}int Heap[maxn],Pos[maxn],siz;//Heap[i]为于i位置上点的编号,pos[i]为i号点在Heap中的位置 , 小根堆void swap(int pos1,int pos2){    Heap[pos1]^=Heap[pos2],Heap[pos2]^=Heap[pos1],Heap[pos1]^=Heap[pos2];    Pos[Heap[pos1]]=pos1,Pos[Heap[pos2]]=pos2;}void shift(int pos){ // 往上调整    while(pos>1){        if(cst[Heap[pos]]<cst[Heap[pos>>1]]) swap(pos,pos>>1);        else return;        pos>>=1;    }}void put(int emt){ // 放入元素    Heap[++siz]=emt;    //printf("%d",Heap[siz]);    Pos[emt]=siz;    shift(siz);}void maintain(int pos){ // 向下调整    int nxt;    while((nxt=pos<<1)<=siz){        (nxt+1<=siz) && (cst[Heap[nxt]]>cst[Heap[nxt+1]]) && (nxt++);        if(cst[Heap[nxt]]>cst[Heap[pos]]) return;        swap(pos,nxt);        pos=nxt;    }}int get(){    int ret=Heap[1];    Heap[1]=Heap[siz--],Pos[Heap[1]]=1;    maintain(1);    return ret;}int prim(){    memset(cst,127/3,sizeof cst);siz=0;    for(int i=1;i<=n;i++)    put(i);    cst[1]=0;    shift(Pos[1]);    int Loc,sum=0;    for(int i=1;i<=n;i++){        Loc=get();        sum+=cst[Loc];        for(int i=fir[Loc];i;i=e[i].nxt)            if(cst[e[i].to]>e[i].w){                cst[e[i].to]=e[i].w;                shift(Pos[e[i].to]);            }    }        return sum;}int main(){    int u,v,w;    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)        scanf("%d%d%d",&u,&v,&w),        Node(u,v,w);    printf("%d",prim());}

原创粉丝点击