zoukankan      html  css  js  c++  java
  • Prim算法

    内置类型pair介绍

    pair的应用

    将两个数据合成一个数据(元组),方便使用。如当一个函数需要返回两个数据,可以返回pair类型。pair的实现是一个结构体。有两个成员:first,second。

    make_pair函数

    template pair make_pair(T1 a, T2 b) { return pair(a, b); }

    usage1: std::make_pair(1, 1.1)

    灵活的方式,会自动进行类型转换,T1为int,T2为double
    

    usage2: std::pair<int, float>(1, 1.1);

    指定T1,T2类型
    

    使用样例

    pair<int, double> p1;            //使用默认构造函数
    pair<int, double> p2(1, 2.4);   //用给定值初始化
    pair<int, double> p3(p2);       //使用p2初始化p3
    
    p1.first=1;
    p1.second=2.5;
    cout<<p1.first<<" "<<p1.second<<endl;
    
    p2=make_pair(1, 1.2);
    

    简化申明

    有时候会觉得使用起来很繁琐,可以使typedef简化申明:

    typedef pair<string, string> author;
    author zuozhe1("Jim", "Green");
    author zuozhe2("Jack", "Brown");
    string s1="W.Bush";
    string s2="George";
    author newone;
    newone=make_pair(s1, s2);
    

    排序

    作为系统内置类型,pair自带排序能力:先比较第一个参数,如果第一个参数相同再比较第二个参数。你可以使用greater<pair<T1, T2> >less<pair<T1, T2> >来控制排序方式。


    朴素Prim复杂度为O(N^2),此Prim算法使用了优先队列优化,复杂度介于O(eloge)~O(nloge)之间,鼓励你使用模板题与Kruskal对比计算效率。

    一般而言,朴素Prim适用于点少边多的情况,Kruskal适用于点多边少的情况。

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef pair<int, int> pii;
    const int maxn=5e3+5, maxm=4e5+5;
    int n, m, head[maxn], nxt[maxm], v[maxm], w[maxm], cnt, dis[maxn];
    bool tag[maxn];											//标记点是否被加入MST 
    void add(int x, int y, int z) { cnt++, v[cnt]=y, w[cnt]=z, nxt[cnt]=head[x], head[x]=cnt; }
    int prim(int s)
    {
        memset(dis, 0x7f, sizeof(dis));						//清空dis数组 
        priority_queue<pii, vector<pii>, greater<pii> > Q;	//小根堆 
        int num=1, ans=0;									//num统计加入MST的点的数量,ans为MST边权和 
        tag[s] = true;
        for(int i=head[s]; i; i=nxt[i])
            if(v[i]!=s)	Q.push(make_pair(w[i], v[i])), dis[v[i]]=min(dis[v[i]], w[i]);
        while(!Q.empty() && num!=n)
        {
            while(!Q.empty() && tag[Q.top().second]) Q.pop();//忽略已加入MST的点 
            if(Q.empty())	break;
            int x=Q.top().second;							//最小dis 
            tag[x]=true, ans+=Q.top().first, num++;			//加入mst 
            Q.pop();
            for(int i=head[x]; i; i = nxt[i])				//使用x松弛与当前MST相连点的dis值
                if(!tag[v[i]] && dis[v[i]]>w[i])		Q.push(make_pair(w[i], v[i])), dis[v[i]]=w[i];
        }
        if (num!=n)	return -1;
        else		return ans;
    }
    
    int main(void)
    {
        scanf("%d%d", &n, &m);
        for(int i=1, x, y, z; i<=m; i++)					//x, y, z放在for内定义可以省一行空间 
    		scanf("%d%d%d", &x, &y, &z), add(x, y, z), add(y, x, z);
        int ans=prim(1);
        if(ans!=-1)	printf("%d
    ", ans);
        else		printf("orz
    ");
        return 0;
    }
    
  • 相关阅读:
    打开LogCat以便查看日志
    sql语句优化
    IIS部署说明
    VM上Hadoop3.1伪分布式模式搭建
    C# 程序结构
    CSS笔记1:属性定位
    VS2013 添加控制台程序
    布局 Layout
    [游泳] 游泳学习课程
    "12306"台前幕后:五年利益之争 仓促上线
  • 原文地址:https://www.cnblogs.com/lfyzoi/p/10472408.html
Copyright © 2011-2022 走看看