题1:
指路:47. 参加科学大会(第六期模拟笔试) (kamacoder.com)
思路与代码:
普通版:
#include<iostream>
#include<vector>
#include<climits>
using namespace std;int main() {int n, m; // n个车站,m个公路cin >> n >> m;int p1, p2, val; // s->e需要v的时间vector<vector<int>> grid (n + 1, vector<int> (n + 1, INT_MAX));for (int i = 0; i < m; i++) {cin >> p1 >> p2 >> val;grid[p1][p2] = val;}int start = 1;int end = n;// 存储从源点到每个节点的最短距离// 初始为最大值vector<int> minDist (n + 1, INT_MAX);// 节点是否被访问过// 初始为falsevector<bool> visited (n + 1, false);minDist[start] = 0; // 起始点到自身的距离为0for (int i = 1; i <= n; i++) {int minVal = INT_MAX;int cur = 1;// 选距离源点最近且未访问的节点for (int v = 1; v <= n; ++v) {if (!visited[v] && minDist[v] < minVal) {minVal = minDist[v];cur = v;}}// 标记该节点已被访问visited[cur] = true;// 3.更新非访问节点到源点的距离(minDist)for (int v = 1; v <= n; v++) {if (!visited[v] && grid[cur][v] != INT_MAX &&minDist[cur] + grid[cur][v] < minDist[v]) {minDist[v] = minDist[cur] + grid[cur][v];}}}if (minDist[end] == INT_MAX) cout << -1 << endl;else cout << minDist[end] << endl;
}
进阶版:
#include<iostream>
#include<vector>
#include<list>
#include<queue>
#include<climits>using namespace std;// 小顶堆
class mycomparison {public :bool operator() (const pair<int, int>& lhs, const pair<int, int>& rhs) {return lhs.second > rhs.second;}
};
// 结构体表示带权重的边
struct Edge {int to; // 邻接顶点int val; // 边的权重Edge(int t, int w) : to(t), val(w) {}; // 构造函数
};int main() {int n, m, p1, p2, val;cin >> n >> m;vector<list<Edge>> grid (n + 1);for (int i = 0; i < m; i++) {cin >> p1 >> p2 >> val;// p1->p2,权值为valgrid[p1].push_back(Edge(p2, val));}int start = 1;int end = n;/// 从源点到每个节点的最短距离vector<int> minDist (n + 1, INT_MAX);// 记录顶点是否被访问过vector<bool> visited (n + 1, false);// 优先队列paie<节点, 源点到节点的权值>priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pq;// 初始化队列pq.push(pair<int, int> (start, 0));minDist[start] = 0; // 起点到自身距离为0while (!pq.empty()) {// 1.选源点到哪个节点近且该节点未被访问过pair<int, int> cur = pq.top();pq.pop();if (visited[cur.first]) continue;// 2.该节点被访问过,visited数组对应值更新为truevisited[cur.first] = true;// 3.更新非访问节点到源点的距离(minDist)for (Edge edge : grid[cur.first]) {if (!visited[edge.to] && minDist[cur.first] + edge.val < minDist[edge.to]) {minDist[edge.to] = minDist[cur.first] + edge.val;pq.push(pair<int, int> (edge.to, minDist[edge.to]));}}}if (minDist[end] == INT_MAX) cout << -1 << endl; // 不符合条件else cout << minDist[end] << endl; // 符合条件
}
总结:
不是,这个题我真不会,太难了。我看了思路觉得还行,但是我看代码之后就越来越不会了。等我慢慢学会吧。