【每日一题】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)\)),因此可以用深度优先搜索
- 以颜色为第一优先级分类,分别将相连的 \(a_i, b_i\) 作标记
- 查询时,遍历所有颜色 \(c_i\),记录在当前颜色下,\(a_i\) 可以访问到的所有节点
- 根据记录结果查看目标节点 \(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)\) 时仍会返回自己
本文来自博客园,作者:HelloEricy,转载请注明原文链接:https://www.cnblogs.com/HelloEricy/p/17518685.html