代码随想录算法训练营第五十三天|图论part4

110.字符串接龙

题目链接: 110. 字符串接龙
文章讲解: 代码随想录

思路:

把每个字符串看成图的一个节点。

转换为求无权图两节点的的最短路径。求最短路径用bfs

cpp 复制代码
#include <string>
#include <vector>
#include <iostream>
#include <queue>
#include <unordered_map>
using namespace std;
unordered_map<int, int>mymap;

bool canTransform(string a, string b) {
    int count = 0;
    if (a.size() != b.size())return false;
    int size = min(a.size(), b.size());
    for (int i = 0; i < size; i++) {
        if (a[i] != b[i])count++;
    }
    if (count == 1)return true;
    else return false;
}

//广搜求最短路径
int bfs(vector<vector<bool>>graph, int begin, int end) {
    queue<int>mq;
    mq.push(begin);
    while (!mq.empty()) {
        int curStr = mq.front();
        if (curStr == end) { return mymap[end]; }
        mq.pop();
        for (int i = 0; i < graph.size(); i++) {
            if (graph[curStr][i] == true && !mymap.count(i)) {
                //mymap.count(i)防止走回头路
                mymap[i] = mymap[curStr] + 1;
                mq.push(i);
            }
        }
    }
    return 0;
}

int main() {
    //数据读取
    mymap[0] = 1;  //初始化不能在全局领域初始化
    int n;
    string beginStr, endStr;
    cin >> n;
    cin >> beginStr >> endStr;
    vector<string>strList;
    strList.push_back(beginStr);
    int size = n;  //使用while(n--)会改变n的值
    while (size--) {
        string str;
        cin >> str;
        strList.push_back(str);
    }
    strList.push_back(endStr);
    //构造图
    vector<vector<bool>>graph(n + 2, vector<bool>(n + 2, false));
    for (int i = 0; i < graph.size(); i++) {
        for (int j = 0; j < graph.size(); j++) {
            if (canTransform(strList[i], strList[j]))graph[i][j] = true;
        }
    }

    int ans = 0;
    ans = bfs(graph, 0, n + 1);
    cout << ans;
}

105.有向图的完全可达性

题目链接:105. 有向图的完全联通

文章讲解:代码随想录

思路:

用深搜

逐渐遍历看第一个节点能不能到达其他节点

错误深搜:

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

bool dfs(vector<pair<int, int>>graph, int begin, int end) {
    if (begin == end)return true;
    for (int i = 0; i < graph.size(); i++) {
        int first = graph[i].first;
        int second = graph[i].second;
        if (first == begin) {
            if (dfs(graph, second, end))break;
        }
    }
    return false;
}

int main() {
    int  n, k;
    cin >> n >> k;
    vector<pair<int, int>>graph;
    for (int i = 0; i < k; i++) {
        int s, t;
        cin >> s >> t;
        graph.push_back({ s,t });
    }
    int ans = 1;
    for (int i = 2; i <= n; i++) {
        if (!dfs(graph, 1, i)) { ans = -1; }
    }
    cout << ans;

}

错误原因:

没有visited记录已经访问过的节点 ,导致陷入死循环。

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

bool dfs(vector<pair<int, int>>graph,vector<bool>&visited, int begin, int end) {
    visited[begin]=true;     //visited记录已经访问过的节点
    if (begin == end)return true;
    for (int i = 0; i < graph.size(); i++) {
        int first = graph[i].first;
        int second = graph[i].second;
        if (first == begin&&visited[second]==false) {
            if(dfs(graph,visited, second, end))return true;
        }
    }
    return false;
}

int main() {
    int  n, k;
    cin >> n >> k;
    vector<pair<int, int>>graph;
    for (int i = 0; i < k; i++) {
        int s, t;
        cin >> s >> t;
        graph.push_back({ s,t });
    }
    int ans = 1;
    for (int i = 2; i <= n; i++) {
        vector<bool>visited(n,false);
        if (!dfs(graph, visited,1, i)) { ans = -1; }
    }
    cout << ans;

}

106.岛屿的周长

题目链接:106. 岛屿的周长

文章讲解:代码随想录

思路:

遍历所有陆地,统计其四个方向 如果是海 则边数+1

不要用惯性思维用深搜

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
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 ans=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||nexty<0||nextx>=grid.size()||nexty>=grid[0].size()){
                        ans+=1;
                        continue;
                    }
                    if(grid[nextx][nexty]==0)ans++;
                }
            }
        }
    }
    cout<<ans;
}
相关推荐
wuyk55510 小时前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论
-dzk-12 小时前
【图论】LC 994.腐烂的橘子
图论
-dzk-1 天前
【图论】LC 200.岛屿数量
深度优先·图论
Lyyaoo.3 天前
【图论】岛屿数量/腐烂的橘子/课程表/实现前缀树
图论
lvwangshu4 天前
图论:LCA、树的直径、树的重心、二分图与 Tarjan 缩点
算法·图论
hansang_IR6 天前
【题解】[APIO2023] 赛博乐园 / cyberland
c++·算法·图论
aqiu1111117 天前
【并查集 / 图论】蓝桥云课 - 魔法大陆的城市群(求无向图连通块数量)题解
蓝桥杯·图论
lvwangshu11 天前
P6534 [COCI 2015/2016 #1] UZASTOPNI 等差树列 题解
动态规划·图论·题解·性质题
positive_zpc15 天前
进阶数据结构图——关键路径(四)
数据结构·图论·关键路径
云淡风轻~窗明几净15 天前
宇宙管理学猜想
算法·图论