马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
图论
题目
110. 字符串接龙
给出开始与结束的字符串,给出字符串 list,返回从字符串开始到结束过程中最短的路径
难点在于:求出发点与尽头的最短路径,通过广度优先搜刮实现
对原始的字符串逐个位进行替换,匹配是否出现在 list 中,出现了就记录到 map 中,直到找到字符
在无权图中,用广搜求最短路最为合适,广搜只要搜到了尽头,那么肯定是最短的路径。因为广搜就是以出发点中心向附近扩散的搜刮。
本题如果用深搜,会比力麻烦,要在到达尽头的不同路径中选则一条最短路。
- #include <iostream>
- #include <vector>
- #include <unordered_map>
- #include <unordered_set>
- #include <string>
- #include <queue>
- using namespace std;
- int main() {
- // 数据处理
- int n;
- string beginStr, endStr, str;
- unordered_set<string> strSet;
- cin >> n;
- cin >> beginStr >> endStr;
- for (int i = 0; i < n; ++i) {
- cin >> str;
- strSet.insert(str);
- }
- // 记录访问情况
- unordered_map<string, int> vis;
- queue<string> que;
- que.push(beginStr);
- vis.insert(make_pair(beginStr, 1));
- // 广度优先搜索遍历
- while (!que.empty()) {
- string word = que.front();
- que.pop();
- // 记录路径长度
- int path = vis[word];
- for (int i = 0; i < word.size(); ++i) {
- string newWord = word;
- for (int j = 0; j < 26; ++j) {
- newWord[i] = j + 'a';
- // 经过变换到达了目标字符
- if (newWord == endStr) {
- cout << path + 1 << endl;
- return 0;
- }
- // 记录字符变化过程
- if (strSet.find(newWord) != strSet.end() && vis.find(newWord) == vis.end()) {
- vis.insert({newWord, path+1});
- que.push(newWord);
- }
- }
- }
- }
- // 找不到变换路径
- cout << 0 << endl;
- }
复制代码 105. 有向图的完全联通
有向图的连通性判定,判定 1 是否可以到达所有节点
思路就是构造有向图,然后遍历图标记节点为 vis 为 true,最后遍历节节点,全为 true 则阐明可访问
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <list>
- using namespace std;
- void dfs(vector<list<int>>& graph, vector<bool>& vis, int idx) {
- if (vis[idx]) return;
- vis[idx] = true;
- for (int key : graph[idx]) {
- dfs(graph, vis, key);
- }
- }
- // 需要预先处理vis[1] = ture
- void dfs2(vector<list<int>>& graph, vector<bool>& vis, int idx) {
- for (int key : graph[idx]) {
- if (!vis[idx]) {
- vis[idx] = true;
- dfs(graph, vis, key);
- }
- }
- }
- void bfs(vector<list<int>>& graph, vector<bool>& vis) {
- queue<int> que;
- que.push(1);
- vis[1] = true;
- while (!que.empty()) {
- list<int> lists = graph[que.front()];
- que.pop();
- for (int key: lists) {
- if (!vis[key]) {
- vis[key] = true;
- que.push(key);
- }
- }
- }
- }
- int main() {
- // 构造图结构
- int n, k;
- cin >> n >> k;
- // 使用邻接表构造
- vector<list<int>> graph(n+1);
- vector<bool> vis(n+1, false);
- for (int i = 0; i < k; ++i) {
- int s, t;
- cin >> s >> t;
- graph[s].push_back(t);
- }
- // 遍历图并检查是否完全访问
- bfs(graph, vis);
- // dfs(graph, vis, 1);
- for (int i = 1; i < n; ++i) {
- if (!vis[i]) {
- cout << -1 <<endl;
- return 0;
- }
- }
- cout << 1 << endl;
- return 0;
- }
复制代码 106. 岛屿的周长
岛屿周长不需要 DFS or BFS 只需要判定当前岛的附近如果是海洋大概是边界 +1 即可
有些岛屿题没那么难
- #include <iostream>
- #include <vector>
- using namespace std;
- int main() {
- // 输入处理
- int n,m;
- cin >> n >> m;
- vector<vector<int>> grid(n, vector<int>(m, 0));
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- cin >> grid[i][j];
- }
- }
- // 遍历计算周长
- int res = 0;
- int dir[4][2] = {0,-1,-1,0,0,1,1,0};
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < m; ++j) {
- // 找到陆地
- if (grid[i][j] == 1) {
- for (int k = 0; k < 4; ++k) {
- int nextX = i + dir[k][0];
- int nextY = j + dir[k][1];
- if (nextX < 0 || nextX >= n || nextY < 0 || nextY >= m || grid[nextX][nextY] == 0) res++;
- }
- }
- }
- }
- cout << res << endl;
- return 0;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|