最大生成树heap实现

本文详细介绍了如何使用C++实现Prim或Kruskal算法的堆优化版本来构建最大生成树。通过优先队列(heap)提高查找最小边的效率,有效地减少了时间复杂度,从而在大规模图数据中提升算法性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

#include <iostream>
#include <array>
#include <set>
using namespace std;

class edge{
public:
    int long long value;
    int long long from;
    int long long to;
    edge(int long long f,int long long t,int long long v){
        value=v;
        from=f;
        to=t;
    }
    edge(){
        value=0;
        from=0;
        to=0;
    }


};

class maxheap{
public:
    edge *heap;
    int long long min;
    int long long size;
    int long long cap;
    int long long left(int long long pos){
        return pos*2+1;
    }
    int long long right(int long long pos){
        return pos*2+2;
    }
    int long long parent(int long long pos){
        return (pos-1)/2;
    }
    bool isleaf(int long long pos){
        return(pos<size&&pos>=(size-1)/2);
    }
    void swap(int long long x,int long long y){
        edge temp=heap[x];
        heap[x]=heap[y];
        heap[y]=temp;
    }
    void down(int long long pos){
        if(size==2){
            if (heap[0].value<heap[1].value) swap(0,1);
        }
        while(!isleaf(pos)){
            int long long max=heap[left(pos)].value;
            int long long pmax=left(pos);
            if(max<heap[right(pos)].value&&pmax<size){
                max=heap[right(pos)].value;
                pmax=right(pos);
            }
            if (heap[pos].value<max){
                swap(pos,pmax);
            }
            pos=pmax;
        }
    }
    maxheap(int long long c){
        heap=new edge[c];
        cap=c;
        size=0;
        min=1000000;
    }
    edge deletepos(){
        edge revalue=heap[0];
        if (size==1) {
            min=0;
            size=0;
            heap[0]=edge();
            return revalue;
        }
        heap[0]=heap[size-1];
        size=size-1;
        down(0);
        return revalue;
    }
    void addpos(int long long value,int long long f,int long long t){
        if(size==cap) return;
        if (value<min) min=value;
        heap[size]=edge(f,t,value);
        int long long pos=size;
        size=size+1;
        while(pos!=0){
            int long long p=parent(pos);
            if (heap[p].value>=heap[pos].value) break;
            swap(pos,p);
            pos=p;
        }
    }
};
int long long fac(int long long num){
    int long long f=0;
    for(int long long i=1;i<num;i++){
        f=f+i;
    }
    return f;
}
bool cir(set<int long long> *node,int long long f,int long long t);
void showset(set<int long long> all);


int long long maxpop(maxheap h,int long long num){
    int long long sumpop=0;
    int long long count=0;
    int long long node[num+1];
    set<int long long> neib[num+1];
    for(int long long i=0;i<num+1;i++){
        node[i]=i;
        neib[i].insert(i);
    }
    while(count!=num-1&&h.size!=0){
        edge e=h.deletepos();
        if(node[e.from]!=node[e.to]){
            count++;
            sumpop=sumpop+e.value;
            if (node[e.from]<node[e.to]){
                for(set<int long long>::iterator i=neib[node[e.to]].begin();i!=neib[node[e.to]].end();i++){
                    if(*i!=e.to)node[*i]=node[e.from];
                    neib[node[e.from]].insert(*i);
                }
                node[e.to]=node[e.from];
            }

            else{
                for(set<int long long>::iterator i=neib[node[e.from]].begin();i!=neib[node[e.from]].end();i++){

                    if(*i!=e.from)node[*i]=node[e.to];
                    neib[node[e.to]].insert(*i);
                }
                node[e.from]=node[e.to];
            }
        }
    }
    return sumpop;
}

void showset(set<int long long> all){
    for(set<int long long>::iterator i=all.begin();i!=all.end();i++){
        cout<<*i<<" ";
    }
}


int main()
{
    int long long team;
    int long long maximun;
    int long long pop;
    cin>>team;
    cin>>maximun;
    maxheap h=maxheap(fac(team));
    int long long teamlist[team];
    for (int long long i=0;i<team;i++){
        cin>>pop;
        teamlist[i]=pop;
    }
    for (int long long i=0;i<team;i++){
        for (int long long k=i+1;k<team;k++){
            if(teamlist[i]*teamlist[k]<maximun) {
                h.addpos(teamlist[i]*teamlist[k],i,k);
            }
            else{
                h.addpos((teamlist[i]*teamlist[k])%maximun,i,k);
            }
        }
    }
    cout<<maxpop(h,team)<<endl;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值