【每日一题】Problem 505B. Mr. Kitayuta's Colorful Graph

原题

解决思路

考虑到数据量不大(\(2 \le n \le 100, 2 \le m \le 100, 1 \le a_i \lt b_i \le n, 1 \lt c_i \le m)\)),因此可以用深度优先搜索

  1. 以颜色为第一优先级分类,分别将相连的 \(a_i, b_i\) 作标记
  2. 查询时,遍历所有颜色 \(c_i\),记录在当前颜色下,\(a_i\) 可以访问到的所有节点
  3. 根据记录结果查看目标节点 \(b_i\) 是否可以被访问到
#include <bits/stdc++.h>

int conn[101][101][101]{};

void dfs(int color, int node, std::vector<bool> &reach) {
  reach[node] = true;
  for (int i = 1; i <= 100; ++i) {
    if (conn[color][node][i]) {
      if (reach[i]) continue;
      dfs(color, i, reach);
    }
  }
}

int main() {
  int t;
  t = 1;
  while (t--) {
    int n, m; std::cin >> n >> m;
    for (int i = 0; i < m; ++i) {
      int a, b, c; std::cin >> a >> b >> c;
      conn[c][a][b] = 1;
      conn[c][b][a] = 1;
    }

    int q; std::cin >> q;
    while (q--) {
      int ans = 0;
      int u, v; std::cin >> u >> v;
      for (int c = 1; c <= m; ++c) {
        std::vector<bool> reach(101, false);
        dfs(c, u, reach);
        if (reach[v]) ++ans;
      }
      std::cout << ans << "\n";
    }
  }
  return 0;
}

更好的解

在看别人提交的代码时,发现只需要二维数组即可。
快速了解并查集

#include <bits/stdc++.h>

int set[101][101]{};

/**
 * union-find finds the root node of the tree which node node belongs to
 */
int find(int color, int node) {
  if (set[color][node] == 0) {
    // if node is new, assume that it is leader
    return node;
  } else {
    // find leader(root node)
    return find(color, set[color][node]);
  }
}

int main() {
  int n, m; std::cin >> n >> m;
  int a, b, c;
  for (int i = 0; i < m; ++i) {
    std::cin >> a >> b >> c;
    int aroot = find(c, a);
    int broot = find(c, b);
    // union set a and set b if they are different set
    // note: this is not quick-union
    if (aroot != broot) set[c][aroot] = broot;
  }
  int q; std::cin >> q;
  int u, v;
  while (q--) {
    int ans = 0;
    std::cin >> u >> v;
    for (int c = 1; c <= m; ++c) {
      if (find(c, u) == find(c, v)) ++ans;
    }
    std::cout << ans << "\n";
  }
  return 0;
}

误区

注意:当 \(set[color][node] == 0\) 为 true 时,不能直接 \(set[color][node] = node\),否则会导致接下来寻找 \(root\) 会一直递归导致段错误。
尽管如此,由于 leader 不会被 \(set[color][node]\) 记录,因此最终 \(find(color, leader)\) 时仍会返回自己

posted @ 2023-07-01 00:41  HelloEricy  阅读(3)  评论(0编辑  收藏  举报