20170829_Dijstra

使用优先队列优化:
只是对点的选择起作用,mindis数组仍保留。

//
//  main.cpp
//  Dijkstra_priorityqueue
//
//  Created by Haoying Zhao on 17/8/29.
//  Copyright © 2017年 Haoying Zhao. All rights reserved.
//

#include <iostream>
#include <queue>

using namespace std;
#define N 6
#define MAX 101
typedef pair<int, int> point;

struct cmp {
    bool operator ()(const point A, const point B) {
        if(A.second == B.second)
            return A.first < B.first;
        return A.second > B.second;
    }
};

int main(int argc, const char * argv[]) {
    int a[N][N];
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
            if(i != j) a[i][j] = MAX;
            else a[i][j] = 0;
    a[0][1] = 6; a[1][0] = 6;a[0][2] = 3; a[2][0] = 3;
    a[1][2] = 2; a[2][1] = 2;a[1][3] = 5; a[3][1] = 5;
    a[2][3] = 3; a[3][2] = 3;a[2][4] = 4; a[4][2] = 4;
    a[3][5] = 3; a[5][3] = 3;a[3][4] = 2; a[4][3] = 2;
    a[4][5] = 5; a[5][4] = 5;
    int mindis[N];
    for(int i = 0; i < N; i++)
        mindis[i] = MAX;
    priority_queue<point,vector<point>,cmp> point_queue;
    point_queue.push(make_pair(0, 0));
    int parent[N];
    memset(parent, 0, sizeof(parent));
    int flag[N];
    memset(flag, 0, sizeof(flag));
    while(!point_queue.empty()) {
        point pos = point_queue.top();
        point_queue.pop();
        if(flag[pos.first] == 1)
            continue;
        flag[pos.first] = 1;
        for(int i = 0 ; i < N; i++) {
            if(a[pos.first][i] == MAX)
                continue;
            if(mindis[i] > pos.second + a[pos.first][i]) {
                mindis[i] = pos.second + a[pos.first][i];
                parent[i] = pos.first;
                point_queue.push(make_pair(i,mindis[i]));
            }
        }
    }
    cout << "mindis: " << endl;
    for(int i = 0; i < N; i++)
        cout << mindis[i] << " ";
    cout << endl << "parent: " << endl;
    for(int i = 0; i < N; i++)
        cout << parent[i] << " ";
    cout << endl << "track: " << endl;
    for(int i = 0; i < N; i++) {
        cout << (char)('A'+i);
        int j = i;
        while(1) {
            if(j == 0)
                break;
            cout << "<---" << (char)('A'+parent[j]);
            j = parent[j];
        }
        cout << endl;
    }
    return 0;
}

反思:
1、优先队列的pop返回值是void,需要先top再pop。
2、此题优先队列中插入了很多多余点,比如两个点先后作为parent给第三点更新最小距离,则会插入两次。多余的点因为排在最优元素之后均不能更新其他点,因此出队时不会造成影响。使用flag可以避免查找,减枝。
3、优先队列的排序问题:
1)直接把需要排序的值放前,使用greater和less调节。
2)定义类,重载运算符<。使用class,须在public:下,struct则不用。

#include <iostream>
#include <queue>
using namespace std;

class point {
    public:
    int x;
    point(int t) {
        x = t;
    }
    bool operator < (const point A) const {
        return this->x > A.x;
    }
};

int main(int argc, const char * argv[]) {
    
    priority_queue<point> xx;
    xx.push(point(5));
    xx.push(point(4));
    xx.push(point(3));
    int i = 0;
    while(!xx.empty()) {
        i++;
        cout << i << ": " << xx.top().x << endl;
        xx.pop();
    }
    return 0;
}

友元函数:

#include <iostream>
#include <queue>
using namespace std;

class point {
    public:
    int x;
    point(int t) {
        x = t;
    }
    friend bool operator < (const point A, const point B) {
        return A.x > B.x;
    }
};


int main(int argc, const char * argv[]) {
    
    priority_queue<point> xx;
    xx.push(point(5));
    xx.push(point(4));
    xx.push(point(3));
    int i = 0;
    while(!xx.empty()) {
        i++;
        cout << i << ": " << xx.top().x << endl;
        xx.pop();
    }
    return 0;
}

3)新建struct,重载运算符()。

#include <iostream>
#include <queue>
using namespace std;

struct cmp {
    bool operator ()(const int A, const int B) {
        return A > B;
    }
};


int main(int argc, const char * argv[]) {
    
    priority_queue<int,vector<int>,cmp> x;
    x.push(5);
    x.push(3);
    x.push(4);
    int i = 0;
    while(!x.empty()) {
        i++;
        cout << i << ": " << x.top() << endl;
        x.pop();
    }
    return 0;
}

使用邻接矩阵:

//
//  main.cpp
//  dijkstra2
//
//  Created by Haoying Zhao on 17/8/29.
//  Copyright © 2017年 Haoying Zhao. All rights reserved.
//

#include <iostream>
#include <queue>
using namespace std;
#define N 6
#define MAX 101
typedef pair<int, int> point;

int main(int argc, const char * argv[]) {
    vector<point> a[N];
    a[0].push_back(make_pair(6, 1));a[1].push_back(make_pair(6, 0));
    a[0].push_back(make_pair(3, 2));a[2].push_back(make_pair(3, 0));
    a[1].push_back(make_pair(2, 2));a[2].push_back(make_pair(2, 1));
    a[1].push_back(make_pair(5, 3));a[3].push_back(make_pair(5, 1));
    a[2].push_back(make_pair(3, 3));a[3].push_back(make_pair(3, 2));
    a[2].push_back(make_pair(4, 4));a[4].push_back(make_pair(4, 2));
    a[3].push_back(make_pair(3, 5));a[5].push_back(make_pair(3, 3));
    a[3].push_back(make_pair(2, 4));a[4].push_back(make_pair(2, 3));
    a[4].push_back(make_pair(5, 5));a[5].push_back(make_pair(5, 4));
    int mindis[N];
    int flag[N];
    int parent[N];
    memset(flag, 0, N);
    for(int i = 0; i < N; i++)
        mindis[i] = MAX;
    mindis[0] = 0;
    memset(parent, 0, N);
    priority_queue<point,vector<point>,greater<point>> q;
    q.push(make_pair(0, 0));
    while(!q.empty()) {
        point x = q.top();
        q.pop();
        if(flag[x.second] == 1)
            continue;
        flag[x.second] = 1;
        for(vector<point>::iterator it = a[x.second].begin(); it != a[x.second].end(); ++it) {
            if(mindis[it->second] > x.first + it->first) {
                mindis[it->second] = x.first + it->first;
                parent[it->second] = x.second;
                q.push(make_pair(mindis[it->second], it->second));
            }
        }
    }
    for(int i = 0; i < N; i++)
        cout << mindis[i] << "  ";
    cout << endl;
    for(int i = 0; i < N; i++) {
        cout << (char)('A'+i);
        int m = parent[i];
        while(1) {
            cout << "<----" << (char)(m+'A');
            if(m == 0) break;
            m = parent[m];
        }
        cout << endl;
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,348评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,122评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,936评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,427评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,467评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,785评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,931评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,696评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,141评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,483评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,625评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,291评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,892评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,492评论 2 348

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,511评论 1 51
  • 重新系统学习下C++;但是还是少了好多知识点;socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme阅读 19,826评论 0 50
  • 前言: 详细介绍: List:元素有放入顺序,元素可重复Map:元素按键值对存储,无放入顺序Set:元素无放入顺序...
    YBshone阅读 8,626评论 0 17
  • 一、 C/C++程序基础 面试例题1——分析代码写输出(一般赋值语句的概念和方法)。 面试例题2—...
    LuckTime阅读 1,970评论 2 42
  • 特朗普的素质令人咂舌,他的竞选在鄙人眼中实为一场闹剧。 不得不说特朗普本身便善于造成舆论,他的言辞极具煽动性,大胆...
    浅海息鱼阅读 73评论 0 0