题解:CF547D Mike and Fish
搞笑题。
题意:很简单了,不再赘述。
做法:
\(x\) 在走到黑色点路径的最小标号这个东西等于将 \(x\) 暂时认为是黑点,然后将黑色点之间的点全部染黑成一个连通块,求这个连通块的最小值就是答案。
那我们考虑直接将第一个黑点拿出来作为根,那么连通块的最小值就等于每个黑点到根的路径上点标号的最小值,很容易处理出来每个节点到根的路径上点标号的最小值 \(val_u\)。然后更改颜色,就直接对答案和 \(val_u\) 取较小值,询问答案,就输出答案和 \(val_u\) 的较小值。
复杂度 \(O(n)\)
不知道该怎么把这个搞笑题说的更详细了,不懂就看代码吧。
要不降个绿吧。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5, N = 1e6;
int n, m, lst, ans = 2e9, rt, val[maxn];
vector<int> e[maxn];
void dfs(int u, int fa) {
if(!fa)
val[u] = u;
for (int i = 0; i < e[u].size(); i++) {
int v = e[u][i];
if(v == fa)
continue;
val[v] = min(val[u], v);
dfs(v, u);
}
}
signed main() {
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i < n; i++) {
int x, y; cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
while(m--) {
int t, z; cin >> t >> z;
z = (z + lst) % n + 1;
if(t == 1) {
if(ans == 2e9)
rt = z, dfs(z, 0);
ans = min(ans, val[z]);
}
else
cout << (lst = min(ans, val[z])) << endl;
}
return 0;
}

浙公网安备 33010602011771号