一、 实验目的及任务
1、掌握贪心算法的基本要素 :最优子结构性质和贪心选择性质
2、应用优先队列求单源顶点的最短路径Dijkstra算法,掌握贪心算法。
二、 实验环境
c++
三、 问题描述
给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其它各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。
四、 编程任务
对于给定的赋权图G,编程计算图的单源顶点最短路径
五、 数据输入
由文件input.txt 给出输入数据。第1 行有2 个正整数n 和m,表示给定的图G 有n 个顶点和m条边,顶点编号为1,2,…,n。接下来的m行中,每行有3 个正整数u,v,w,表示图G 的一条边(u,v)及其边权w。
六、 结果输出
将编程计算出单源顶点最短路径结果输出到output.txt。
实验内容
读取input中的数据,将输出结果放入output中
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits>
using namespace std;
typedef pair<int, int> P;
const int MAX_N = 100000;
const int INF = numeric_limits<int>::max();
int n, m;
int start;
int dist[MAX_N + 1];
bool used[MAX_N + 1];
vector<P> G[MAX_N + 1]; // 邻接表表示图
void dijkstra() {
priority_queue<P, vector<P>, greater<P>> pq; // 小根堆
fill(dist, dist + n + 1, INF);
fill(used, used + n + 1, false);
dist[start] = 0;
pq.push(make_pair(0, start));
while (!pq.empty()) {
P p = pq.top();
pq.pop();
int v = p.second;
if (used[v]) continue;
used[v] = true;
for (int i = 0; i < G[v].size(); i++) {
int to = G[v][i].first;
int cost = G[v][i].second;
if (dist[to] > dist[v] + cost) {
dist[to] = dist[v] + cost;
pq.push(make_pair(dist[to], to));
}
}
}
}
int main() {
ifstream infile("input.txt");
ofstream outfile("output.txt");
infile >> n >> m;
for (int i = 0; i < m; i++) {
int u, v, w;
infile >> u >> v >> w;
G[u].push_back(make_pair(v, w));
}
infile >> start;
infile.close();
dijkstra();
for (int i = 1; i <= n; i++) {
if (dist[i] == INF) {
outfile << "INF\n";
} else {
outfile << dist[i] << "\n";
}
}
outfile.close();
return 0;
}