算法训练1-day45-图论

18 阅读3分钟
  1. 110. 字符串迁移 和前面二维数组保存的图本质上其实是相同的,前面的题用二维数组保存节点的关系,本题使用set来保存,通过检查是否在set中来看是不是能够相连;前面的题遍历时是按照上下左右走,本题就是按照26个小写字母来替换每一位
#include <iostream>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int main() {
  unordered_set<string> words;
  int n = 0;
  cin >> n;
  string beginStr, endStr;
  cin >> beginStr >> endStr;
  string word;
  for (int i = 0; i < n; i++) {
    cin >> word;
    words.insert(word);
  }

  unordered_map<string, int> visited;
  queue<string> q;

  // 从beginStr开始bfs找最短路
  visited.emplace(beginStr, 1);
  q.push(beginStr);
  while (!q.empty()) {
    word = q.front();
    q.pop();
    // 检查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 << visited[word] + 1 << endl;
          return 0;
        }
        if (words.find(newword) != words.end() &&
            visited.find(newword) == visited.end()) {
          visited.emplace(newword, visited[word] + 1);
          q.push(newword);
        }
      }
    }
  }

  cout << 0 << endl;
  return 0;
}
  1. 105. 有向图的完全联通 从1开始遍历索引可达节点,记录个数,如果可达节点数等于n,那么就代表1可以到达所有节点
#include <iostream>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

class EdgeNode {
public:
  EdgeNode() { next = -1; }
  EdgeNode(int next) { this->next = next; }

  const int GetNext() { return next; }

private:
  int next;
};

class MyGraph {
public:
  MyGraph() {}

  MyGraph(int n_vertex) {
    vertexes = vector<int>(n_vertex);
    for (int i = 1; i <= n_vertex; i++) {
      vertexes[i - 1] = i;
    }
  }
  void AddVertex(int vertex) { vertexes.push_back(vertex); }

  void AddEdge(int from, int to) {
    if (edges.find(from) == edges.end()) {
      edges[from] = list<EdgeNode *>();
    }
    ////无向图
    // if (edges.find(to) == edges.end()) {
    //	edges[to] = list<EdgeNode*>();
    //}

    edges[from].push_back(new EdgeNode(to));
    // edges[to].push_back(new EdgeNode(from));
  }

  ~MyGraph() {
    for (auto item : edges) {
      for (EdgeNode *edge : item.second) {
        delete edge;
      }
    }
  }

  list<EdgeNode *> GetEdges(int vertex) { return edges[vertex]; }

  void dfs(int beginVertex, vector<bool> &visited, int &count) {
    auto edge = edges[beginVertex];
    for (auto e : edge) {
      if (!visited[e->GetNext()]) {
        count++;
        visited[e->GetNext()] = true;
        dfs(e->GetNext(), visited, count);
      }
    }
  }

private:
  vector<int> vertexes;
  unordered_map<int, list<EdgeNode *>> edges;
};

int main() {
  int n = 0, m = 0;
  cin >> n >> m;

  MyGraph graph(n);

  int from = 0, to = 0;
  for (int i = 0; i < m; i++) {
    cin >> from >> to;
    graph.AddEdge(from, to);
  }

  int count = 1;
  vector<bool> visited(n + 1);
  visited[1] = true;
  graph.dfs(1, visited, count);

  cout << (count == n ? 1 : -1) << endl;

  return 0;
}
  1. [106. 海岸线计算]](kamacoder.com/problempage…) 找海岸线,就是找每一个陆地,也就是值为1的点周围的海水节点,也就是值为0的节点的个数;海水节点不用记录是否访问过,因为一块海水可能被多个陆地包围;另外,题目假设矩阵外均被水包围,因此我们设置数组的大小为n+2与m+2。
#include <iostream>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右
void dfs(vector<vector<int>> &grid, vector<vector<bool>> &visited, int i, int j,
         int &count) {
  for (auto d : dir) {
    int next_i = i + d[0];
    int next_j = j + d[1];
    if (next_i < 0 || next_i >= grid.size() || next_j < 0 ||
        next_j >= grid[0].size()) {
      continue;
    }
    if (grid[next_i][next_j] == 0) {
      count++;
    }
    if (!visited[next_i][next_j] && grid[next_i][next_j] == 1) {
      visited[next_i][next_j] = true;
      dfs(grid, visited, next_i, next_j, count);
    }
  }
}

int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<int>> grid(n + 2, vector<int>(m + 2, 0));
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      cin >> grid[i][j];
    }
  }

  vector<vector<bool>> visited(n + 2, vector<bool>(m + 2));
  int count = 0;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      if (grid[i][j] == 1) {
        visited[i][j] = true;
        dfs(grid, visited, i, j, count);
        cout << count << endl;
        return 0;
      }
    }
  }
  return 0;
}