dijkstra + 优先队列 最短路 [sdut 2143]

题目描述:最短路裸题


分析: 本身是一道裸题,这次用优先队列做一下dijkstra。也get到了优先队列各种姿势的排序方式,分享一下:
关于dijkstra算法,可以用用优先队列存所有与已被选择的点有关的点,由于要选出距源点最近的点,所以把这些点按dis的大小放进最小堆里,即优先队列。
优先队列的三种排序方式:
1. priority_queue <int> que
这样默认是从大到小排的
2. priority_queue <int, vector<int>, less<int>> que
priority_queue <int, vector<int>, greater <int> > que

第一种 用less作为排序函数,是从大往小排
第二种用greater 作为排序函数,是从小到大排
3. priority_queue <int, vector<int>, cmp> que
这种排序方式是你自己定义的,需要在上面写一个cmp结构体,重载()运算符

struct cmp
{
    bool operator ()(int a, int b)
    {
        return dis[a] > dis[b];//按dis[i]的值从小往大排序
    }
};

这就是优先队列的三种排序方式


题目:
Problem Description
给定一个带权无向图,求节点1到节点n的最短路径。

Input
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表节点个数和边的个数。(n<=100)
剩下m行每行3个正整数a b c,代表节点a和节点b之间有一条边,权值为c。

Output
每组输出占一行,仅输出从1到n的最短路径权值。(保证最短路径存在)

Example Input

3 2
1 2 1
1 3 1
1 0

Example Output

1
0


代码:

#include <bits/stdc++.h>

using namespace std;

int vertex, edge, s, e, cnt, w;
int dis[200], head[200];
struct node
{
    int pos;
    int weight;
    int next;
}eg[60000];

void addnode(int u, int v, int w);
void init();
int dijkstra();
struct cmp
{
    bool operator ()(int a, int b)
    {
        return dis[a] > dis[b];//按dis的值从小到大排序,便于选出
    }                          //集合S外离源点最近的点
};

int main()
{
    while(cin >> vertex >> edge)
    {
        init();
        for(int i=0; i<=edge-1; i++)
        {
            cin >> s >> e >> w;
            addnode(s, e, w);
            addnode(e, s, w);
        }
        cout << dijkstra() << endl;
    }
    return 0;
}

int dijkstra()
{
    priority_queue <int, vector <int>, cmp> que;
    que.push(1);
    dis[1] = 0;
    while(! que.empty())
    {
        int src = que.top();
        que.pop();
        for(int i=head[src]; i!=-1; i=eg[i].next)
        {
            int tar = eg[i].pos;
            int weight = eg[i].weight;
            if(dis[tar] > dis[src] + weight)
            {
                dis[tar] = dis[src] + weight;
                que.push(tar);
            }
        }
    }
    return dis[vertex];
}

void init()
{
    cnt = 0;
    memset(dis, 63, sizeof(dis));
    memset(head, -1, sizeof(head));
}

void addnode(int u, int v, int w)
{
    eg[cnt].pos = v;
    eg[cnt].weight = w;
    eg[cnt].next = head[u];
    head[u] = cnt ++;
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值