出差
Bellman-Ford
cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<int> dis(n, 0x3f3f3f3f);
vector<int> time(n);
vector<vector<int>> gra(m, vector<int>(3));
dis[0] = 0;
for (int i = 0; i < n; i++)
{
cin >> time[i];
}
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
a--;
b--;
gra.push_back({a, b, c});
gra.push_back({b, a, c});
}
for (int cnt = 1; cnt < n; cnt++)
{
for (int i = 0; i < gra.size(); i++)
{
int from = gra[i][0];
int to = gra[i][1];
int val = gra[i][2];
int stay = time[to];
if (dis[from] != 0x3f3f3f3f && dis[from] + val + stay < dis[to])
{
dis[to] = dis[from] + val + stay;
}
}
}
cout << dis[n - 1] - time[n - 1];
return 0;
}
Dijkstra
字母阶梯游戏
Bellman-Ford
cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<vector<int>> gra;
vector<string> s(n);
for (int i = 0; i < n; i++)
{
cin >> s[i];
}
int len = s[0].size();
string a, b;
cin >> a >> b;
int si,ei;
for(int i=0;i<n;i++){
if(s[i]==a){
si = i;
}
if(s[i]==b){
ei = i;
}
}
vector<int> dis(n, 0x3f3f3f3f);
dis[si] = 0;
for (int i = 0; i < s.size(); i++)
{
for (int j = i + 1; j < s.size(); j++)
{
int cnt = 0;
for (int k = 0; k < len; k++)
{
if (s[i][k] != s[j][k])
{
cnt++;
}
}
if (cnt == 1)
{
gra.push_back({i, j});
gra.push_back({j, i});
}
}
}
for (int cnt = 1; cnt < n; cnt++)
{
for (int i = 0; i < gra.size(); i++)
{
int from = gra[i][0];
int to = gra[i][1];
int val = 1;
if (dis[from] != 0x3f3f3f3f && dis[from] + val < dis[to])
{
dis[to] = dis[from] + val;
}
}
}
if (dis[ei] == 0x3f3f3f3f)
{
cout << -1;
}
else
{
cout << dis[ei];
}
return 0;
}
Dijkstra
BFS
更优解法:BFS(推荐)
单词阶梯问题本质是未加权图的最短路径,BFS 更高效(时间复杂度 O(N·L·26))。思路:
-
使用哈希集合存储所有单词,便于快速查找。
-
从开始单词 BFS:
-
队列存储当前单词及其距离。
-
对当前单词的每个位置,尝试替换为其他 25 个字母,生成新单词。
-
如果新单词在集合中且未访问,入队并记录距离。
-
-
到达结束单词时返回距离;队列空未找到则返回 -1。
代码实现:
cpp
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>
#include <string>
using namespace std;
int main() {
int n;
cin >> n;
vector<string> words(n);
for (int i = 0; i < n; i++) {
cin >> words[i];
}
string begin_word, end_word;
cin >> begin_word >> end_word;
unordered_set<string> dict(words.begin(), words.end());
unordered_map<string, int> dist; // 记录每个单词的距离
queue<string> q;
// 初始化 BFS
dist[begin_word] = 0;
q.push(begin_word);
while (!q.empty()) {
string u = q.front();
q.pop();
// 到达结束单词,输出距离(即变化步数)
if (u == end_word) {
cout << dist[u] << endl;
return 0;
}
// 尝试修改单词的每个位置
for (int i = 0; i < u.size(); i++) {
char original = u[i];
for (char c = 'a'; c <= 'z'; c++) {
if (c == original) continue;
string v = u; // 生成新单词
v[i] = c;
// 如果新单词在字典中且未访问
if (dict.find(v) != dict.end() && dist.find(v) == dist.end()) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
}
}
cout << -1 << endl; // 未找到路径
return 0;
}