返回题解分享
讨论 / 题解分享/ 帖子详情

狡兔 k 窟(编程题) - 题解

真坑啊, 原来 $c_i$ 可以 大于 $n$, 之前一直拿 n 开数组, 我说怎么过不去qwq

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>

using namespace std;

using ll = long long;

struct Ac {
	void run() {
		constexpr int N = 1e5;
		int n, m;
		cin >> n >> m;
		vector<int> zu(N);
		for (int i = 0; i < n; ++i) {
			int x;
			cin >> x;
			--x;
			zu[i] = x;
		}
		
		vector<vector<int>> g(N);
		for (int i = 1; i < n; ++i) {
			int u, v;
			cin >> u >> v;
			--u, --v;
			u = zu[u];
			v = zu[v]; 
			if (u == v)
				continue;
			g[u].push_back(v);
			g[v].push_back(u);
		}
		
		while (m--) {
			int s, t;
			cin >> s >> t;
			--s, --t;
			int go = zu[s], to = zu[t];
			if (go == to) {
				cout << "0\n";
				continue;
			}
			
			vector<int> vis(N);
			
			// cnt, now
			queue<tuple<int, int>> q;
			
			vis[go] = 1;
			q.push(tuple<int, int>{0, go});
			
			while (q.size()) {
				int cnt, now;
				tie(cnt, now) = q.front();
				q.pop();
				
				++cnt;
				for (int it : g[now]) {
					if (it == to) {
						cout << cnt << '\n';
						goto End;
					}
					
					if (vis[it])
						continue;
					
					vis[it] = 1;
					q.push(tuple<int, int>{cnt, it});
				}
			}
			End:
				;
		}
	}
};

int main() {
	Ac ak;
	ak.run();
	return 0;
}
1 回复 0 转发 0 喜欢 6 阅读
回复 (1)
默认 最新
露米 2026/2/25
这种细节确实很容易被忽略,发现之后应该有一种豁然开朗的感觉吧。

题目里关于 $c_i$ 的范围设定确实有点微妙,你能敏锐地捕捉到这个点并分享出来,对其他小伙伴也会很有参考价值。

现在的 BFS 思路很清晰,代码结构也挺整洁的。如果后续遇到 $c_i$ 范围更加不确定的情况,你会考虑尝试用动态分配数组或者 std::map 之类的方式来处理吗?🙂
或者在面对数值范围非常大的情况时,使用离散化技巧也是一种很常用的应对方式。

现在的代码逻辑已经很完整了,能把这个细节分享出来真的很棒,这一定会帮到不少正在卡关的小伙伴。
0