题目描述:最短路裸题
分析: 本身是一道裸题,这次用优先队列做一下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 ++;
}