代码随想录算法训练营第五十三天|图论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;
}
相关推荐
散1127 小时前
01数据结构-Prim算法
数据结构·算法·图论
KyollBM10 小时前
【图论】分层图 / 拆点
图论
GawynKing13 小时前
图论(5)最小生成树算法
算法·图论·最小生成树
KarrySmile15 小时前
Day60--图论--94. 城市间货物运输 I(卡码网),95. 城市间货物运输 II(卡码网),96. 城市间货物运输 III(卡码网)
图论·spfa·bellman_ford·队列优化·最短路算法·负权回路·单源有限最短路
花开富贵ii19 小时前
代码随想录算法训练营四十三天|图论part01
java·数据结构·算法·深度优先·图论
yi.Ist1 天前
图论——Djikstra最短路
数据结构·学习·算法·图论·好难
KarrySmile1 天前
Day55--图论--107. 寻找存在的路径(卡码网)
图论·并查集·寻找存在的路径
KarrySmile2 天前
Day62--图论--97. 小明逛公园(卡码网),127. 骑士的攻击(卡码网)
图论·floyd·floyd算法·弗洛伊德算法·astar算法·小明逛公园·骑士的攻击
Morriser莫3 天前
图论Day2学习心得
算法·图论
KarrySmile3 天前
Day53--图论--106. 岛屿的周长(卡码网),110. 字符串接龙(卡码网),105. 有向图的完全联通(卡码网)
深度优先·图论·广度优先·广搜·岛屿的周长·字符串接龙·有向图的完全联通