当前位置:   article > 正文

算法训练 | 图论Part4 | 110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长

算法训练 | 图论Part4 | 110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长

目录

110.字符串接龙

图论法

105.有向图的完全可达性

图论法

106.岛屿的周长

图论法


110.字符串接龙

图论法
  • 代码一:广搜法

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <unordered_set>
  5. #include <unordered_map>
  6. #include <queue>
  7. using namespace std;
  8. int main() {
  9. string beginStr, endStr, str;
  10. int n;
  11. cin >> n;
  12. unordered_set<string> strSet;
  13. cin >> beginStr >> endStr;
  14. for (int i = 0; i < n; i++) {
  15. cin >> str;
  16. strSet.insert(str);
  17. }
  18. // 记录strSet里的字符串是否被访问过,同时记录路径长度
  19. unordered_map<string, int> visitMap; // <记录的字符串,路径长度>
  20. // 初始化队列
  21. queue<string> que;
  22. que.push(beginStr);
  23. // 初始化visitMap
  24. visitMap.insert(pair<string, int>(beginStr, 1));
  25. while(!que.empty()) {
  26. string word = que.front();
  27. que.pop();
  28. int path = visitMap[word]; // 这个字符串在路径中的长度
  29. // 开始在这个str中,挨个字符去替换
  30. for (int i = 0; i < word.size(); i++) {
  31. string newWord = word; // 用一个新字符串替换str,因为每次要置换一个字符
  32. // 遍历26的字母
  33. for (int j = 0 ; j < 26; j++) {
  34. newWord[i] = j + 'a';
  35. if (newWord == endStr) { // 发现替换字母后,字符串与终点字符串相同
  36. cout << path + 1 << endl; // 找到了路径
  37. return 0;
  38. }
  39. // 字符串集合里出现了newWord,并且newWord没有被访问过
  40. if (strSet.find(newWord) != strSet.end()
  41. && visitMap.find(newWord) == visitMap.end()) {
  42. // 添加访问信息,并将新字符串放到队列中
  43. visitMap.insert(pair<string, int>(newWord, path + 1));
  44. que.push(newWord);
  45. }
  46. }
  47. }
  48. }
  49. // 没找到输出0
  50. cout << 0 << endl;
  51. }

105.有向图的完全可达性

图论法
  • 代码一:深搜法

  1. // 写法一:dfs 处理当前访问的节点
  2. #include <iostream>
  3. #include <vector>
  4. #include <list>
  5. using namespace std;
  6. void dfs(const vector<list<int>>& graph, int key, vector<bool>& visited) {
  7. if (visited[key]) {
  8. return;
  9. }
  10. visited[key] = true;
  11. list<int> keys = graph[key];
  12. for (int key : keys) {
  13. // 深度优先搜索遍历
  14. dfs(graph, key, visited);
  15. }
  16. }
  17. int main() {
  18. int n, m, s, t;
  19. cin >> n >> m;
  20. // 节点编号从1到n,所以申请 n+1 这么大的数组
  21. vector<list<int>> graph(n + 1); // 邻接表
  22. while (m--) {
  23. cin >> s >> t;
  24. // 使用邻接表 ,表示 s -> t 是相连的
  25. graph[s].push_back(t);
  26. }
  27. vector<bool> visited(n + 1, false);
  28. dfs(graph, 1, visited);
  29. //检查是否都访问到了
  30. for (int i = 1; i <= n; i++) {
  31. if (visited[i] == false) {
  32. cout << -1 << endl;
  33. return 0;
  34. }
  35. }
  36. cout << 1 << endl;
  37. }

106.岛屿的周长

图论法
  • 代码一:图论法

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int main() {
  5. int n, m;
  6. cin >> n >> m;
  7. vector<vector<int>> grid(n, vector<int>(m, 0));
  8. for (int i = 0; i < n; i++) {
  9. for (int j = 0; j < m; j++) {
  10. cin >> grid[i][j];
  11. }
  12. }
  13. int sum = 0; // 陆地数量
  14. int cover = 0; // 相邻数量
  15. for (int i = 0; i < n; i++) {
  16. for (int j = 0; j < m; j++) {
  17. if (grid[i][j] == 1) {
  18. sum++; // 统计总的陆地数量
  19. // 统计上边相邻陆地
  20. if(i - 1 >= 0 && grid[i - 1][j] == 1) cover++;
  21. // 统计左边相邻陆地
  22. if(j - 1 >= 0 && grid[i][j - 1] == 1) cover++;
  23. // 为什么没统计下边和右边? 因为避免重复计算
  24. }
  25. }
  26. }
  27. cout << sum * 4 - cover * 2 << endl;
  28. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/804922
推荐阅读
相关标签
  

闽ICP备14008679号