最小生成树-STL写法

本来是POJ里的一道水题,就尝试用不同的思路去写。因为本来就很习惯用STL,所以就干脆写了个STL版本

基本思路就是构建优先队列,不断查询满足以下条件的边:

1、权值尽可能要小
2、边的两端点一个已经入树,一个还未入树
3、如果优先队列排空后仍然没有合适的边,那么就无法构建最小生成树了

下面是题目传送

不过这个程序POJ上跑的时候,最开始内存爆掉了。我减小了maxn以后才AC了。
可能这也是STL的一个缺陷吧。不过个人看来是数组开的稍微大了些,搞得STL容器没内存了。

下面是代码:

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cstdio>
#define mem(s,value) memset(s,value,sizeof(s))
#define frein(s)  freopen(s,"r",stdin)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 1e3;

class Edge{
public:
    int u,v;
    int value;
    Edge(){};
    Edge(int u_,int v_,int value_):u(u_),v(v_),value(value_){};
    bool operator< (const Edge& rhs)const{
        //这里一定要注意,优先队列默认大数在前
        //这里为了让小数在前,就对运算符进行了修改
        return value > rhs.value;
    }
};

priority_queue<Edge> Q;
int vis[maxn];
int mapper[maxn][maxn];
int n,k;
int Value;

//核心代码
int solve(){
    while(!Q.empty())Q.pop();
    vis[1]=1;
    Value = 0;
    int num = n-1;
    int cur = 1;
    while(num--){
        //对于cur结点,找到所有相关的边并压入优先队列
        for(int i=1;i<=n;i++){
            if(mapper[cur][i]){
                Q.push(Edge(cur,i,mapper[cur][i]));
            }
        }
        //寻找当前可用最短边
        Edge aim;
        bool ok=false;
        //事实上寻找的新的合适的边一定是一个连接了二分图的边
        while(!Q.empty()){
            aim = Q.top(); Q.pop();
            if(vis[aim.v])continue;
            ok=true;
            break;
        }
        if(!ok)return 0;//排除找不到的情况
        //计算树
        vis[aim.v]=1;
        Value += aim.value;
        cur = aim.v;
    }
    return 1;
}

int readin(){
    memset(mapper,0,sizeof(mapper));
    memset(vis,0,sizeof(vis));
    scanf("%d",&n);
    if(!n)return 0;
    scanf("%d",&k);
    for(int i=0;i<k;i++){
        int a,b,w;
        scanf("%d %d %d",&a,&b,&w);
        //数据读入这里一定需要注意一下
        if(mapper[a][b]==0){
            mapper[a][b] = mapper[b][a] = w;
        }else{
            w = min(w,mapper[a][b]);
            mapper[a][b] = mapper[b][a] = w;
        }
    }
    return 1;
}

int main(){
    while(readin()){
        solve();
        cout<<Value<<endl;
    }
    return 0;
}

OK

posted @ 2020-10-19 17:18  SavenNeer  阅读(154)  评论(0编辑  收藏  举报