zoukankan      html  css  js  c++  java
  • 最小生成树-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

  • 相关阅读:
    CSS Sprites技术
    js Event对象
    iphone上做webapp时总会识别一串数字为手机号码并变黑显示
    获得touch事件,jquery绑定事件监听器,ios设备上打开touch状态以响应focus,active等伪类
    访问局域网内数据库
    理解javascript的闭包,原型,和匿名函数及IIFE
    socket跟TCP/IP 的关系,单台服务器上的并发TCP连接数问题
    最详细的Log4j使用教程
    [Java IO]06_JSON操作
    mybatis一次执行多条SQL语句
  • 原文地址:https://www.cnblogs.com/savennist/p/13841395.html
Copyright © 2011-2022 走看看