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

发布于:2025-07-26 ⋅ 阅读:(10) ⋅ 点赞:(0)
110.字符串接龙
题目链接: 110. 字符串接龙
文章讲解: 代码随想录

 思路:

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

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


#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. 有向图的完全联通

文章讲解:代码随想录

思路:

用深搜

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

错误深搜:


#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记录已经访问过的节点 ,导致陷入死循环。


#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

不要用惯性思维用深搜

 

#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;
}

 


网站公告

今日签到

点亮在社区的每一天
去签到