代码随想录算法训练营 Day53 图论Ⅳ 字符串接龙 有向图 岛屿周长

[复制链接]
发表于 2025-7-29 19:48:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
图论

题目

110. 字符串接龙
给出开始与结束的字符串,给出字符串 list,返回从字符串开始到结束过程中最短的路径
难点在于:求出发点与尽头的最短路径,通过广度优先搜刮实现
对原始的字符串逐个位进行替换,匹配是否出现在 list 中,出现了就记录到 map 中,直到找到字符
在无权图中,用广搜求最短路最为合适,广搜只要搜到了尽头,那么肯定是最短的路径。因为广搜就是以出发点中心向附近扩散的搜刮。
本题如果用深搜,会比力麻烦,要在到达尽头的不同路径中选则一条最短路
  1. #include <iostream>
  2. #include <vector>
  3. #include <unordered_map>
  4. #include <unordered_set>
  5. #include <string>
  6. #include <queue>
  7. using namespace std;
  8. int main() {
  9.     // 数据处理
  10.     int n;
  11.     string beginStr, endStr, str;
  12.     unordered_set<string> strSet;
  13.     cin >> n;
  14.     cin >> beginStr >> endStr;
  15.     for (int i = 0; i < n; ++i) {
  16.         cin >> str;
  17.         strSet.insert(str);
  18.     }
  19.     // 记录访问情况
  20.     unordered_map<string, int> vis;
  21.     queue<string> que;
  22.     que.push(beginStr);
  23.     vis.insert(make_pair(beginStr, 1));
  24.     // 广度优先搜索遍历
  25.     while (!que.empty()) {
  26.         string word = que.front();
  27.         que.pop();
  28.         // 记录路径长度
  29.         int path = vis[word];
  30.         for (int i = 0; i < word.size(); ++i) {
  31.             string newWord = word;
  32.             for (int j = 0; j < 26; ++j) {
  33.                 newWord[i] = j + 'a';
  34.                 // 经过变换到达了目标字符
  35.                 if (newWord == endStr) {
  36.                     cout << path + 1 << endl;
  37.                     return 0;
  38.                 }
  39.                 // 记录字符变化过程
  40.                 if (strSet.find(newWord) != strSet.end() && vis.find(newWord) == vis.end()) {
  41.                     vis.insert({newWord, path+1});
  42.                     que.push(newWord);
  43.                 }
  44.             }
  45.         }
  46.     }
  47.     // 找不到变换路径
  48.     cout << 0 << endl;
  49. }
复制代码
105. 有向图的完全联通
有向图的连通性判定,判定 1 是否可以到达所有节点
思路就是构造有向图,然后遍历图标记节点为 vis 为 true,最后遍历节节点,全为 true 则阐明可访问
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <list>
  5. using namespace std;
  6. void dfs(vector<list<int>>& graph, vector<bool>& vis, int idx) {
  7.     if (vis[idx]) return;
  8.     vis[idx] = true;
  9.     for (int key : graph[idx]) {
  10.         dfs(graph, vis, key);
  11.     }
  12. }
  13. // 需要预先处理vis[1] = ture
  14. void dfs2(vector<list<int>>& graph, vector<bool>& vis, int idx) {
  15.     for (int key : graph[idx]) {
  16.         if (!vis[idx]) {
  17.             vis[idx] = true;
  18.             dfs(graph, vis, key);
  19.         }
  20.     }
  21. }
  22. void bfs(vector<list<int>>& graph, vector<bool>& vis) {
  23.     queue<int> que;
  24.     que.push(1);
  25.     vis[1] = true;
  26.     while (!que.empty()) {
  27.         list<int> lists = graph[que.front()];
  28.         que.pop();
  29.         for (int key: lists) {
  30.             if (!vis[key]) {
  31.                 vis[key] = true;
  32.                 que.push(key);
  33.             }
  34.         }
  35.     }
  36. }
  37. int main() {
  38.     // 构造图结构
  39.     int n, k;
  40.     cin >> n >> k;
  41.     // 使用邻接表构造
  42.     vector<list<int>> graph(n+1);
  43.     vector<bool> vis(n+1, false);
  44.     for (int i = 0; i < k; ++i) {
  45.         int s, t;
  46.         cin >> s >> t;
  47.         graph[s].push_back(t);
  48.     }
  49.     // 遍历图并检查是否完全访问
  50.     bfs(graph, vis);
  51.     // dfs(graph, vis, 1);
  52.     for (int i = 1; i < n; ++i) {
  53.         if (!vis[i]) {
  54.             cout << -1 <<endl;
  55.             return 0;
  56.         }
  57.     }
  58.     cout << 1 << endl;
  59.     return 0;
  60. }
复制代码
106. 岛屿的周长
岛屿周长不需要 DFS or BFS 只需要判定当前岛的附近如果是海洋大概是边界 +1 即可
有些岛屿题没那么难
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int main() {
  5.     // 输入处理
  6.     int n,m;
  7.     cin >> n >> m;
  8.     vector<vector<int>> grid(n, vector<int>(m, 0));
  9.     for (int i = 0; i < n; ++i) {
  10.         for (int j = 0; j < m; ++j) {
  11.             cin >> grid[i][j];
  12.         }
  13.     }
  14.     // 遍历计算周长
  15.     int res = 0;
  16.     int dir[4][2] = {0,-1,-1,0,0,1,1,0};
  17.     for (int i = 0; i < n; ++i) {
  18.         for (int j = 0; j < m; ++j) {
  19.             // 找到陆地
  20.             if (grid[i][j] == 1) {
  21.                 for (int k = 0; k < 4; ++k) {
  22.                     int nextX = i + dir[k][0];
  23.                     int nextY = j + dir[k][1];
  24.                     if (nextX < 0 || nextX >= n || nextY < 0 || nextY >= m || grid[nextX][nextY] == 0) res++;
  25.                 }
  26.             }
  27.         }
  28.     }
  29.     cout << res << endl;
  30.     return 0;
  31. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

快速回复 返回顶部 返回列表