#include <bits/stdc++.h>
using namespace std;
const int maxN = 3e5 + 5;
vector<pair<int, int>> adj[maxN];
pair<int, int> edge[maxN];
int par[maxN], belong[maxN], ans[maxN], ask[maxN];
int depth[maxN], pos[maxN], RMQ[21][2 * maxN], tick = 0;
void dfs(int u, int pre) {
RMQ[0][++tick] = u; pos[u] = tick;
for (auto it: adj[u]) {
int v = it.first, id = it.second;
if (v == pre) continue;
belong[v] = id;
par[v] = u;
depth[v] = depth[u] + 1;
dfs(v, u);
RMQ[0][++tick] = u;
}
}
/// DSU
int pre[maxN], sz[maxN], Top[maxN];
int find_set(int u) {
return (u == pre[u]) ? u : pre[u] = find_set(pre[u]);
}
void union_set(int u, int v) {
u = find_set(u);
v = find_set(v);
if (u == v) return ;
if (sz[u] < sz[v]) swap(u, v);
pre[v] = u;
sz[u] += sz[v];
if (depth[Top[u]] > depth[Top[v]]) Top[u] = Top[v];
}
int min_depth(int x, int y) {return (depth[x] < depth[y]) ? x : y;};
int getLCA(int u, int v) {
int l = pos[u], r = pos[v];
if (l > r) swap(l, r);
int k = 31 - __builtin_clz(r - l + 1);
return min_depth(RMQ[k][l], RMQ[k][r - (1 << k) + 1]);
}
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
edge[i] = {u, v};
}
for (int i = 1; i < n; i++) {
int id; cin >> id;
auto [u, v] = edge[id];
ask[id] = 1;
adj[u].push_back({v, id});
adj[v].push_back({u, id});
}
depth[1] = 1;
dfs(1, 1);
for (int j = 1; (1 << j) <= tick; j++)
for (int i = 1; i <= tick - (1 << j) + 1; i++)
RMQ[j][i] = min_depth(RMQ[j - 1][i], RMQ[j - 1][i + (1 << (j - 1))]);
for (int i = 1; i <= n; i++) {
pre[i] = i;
sz[i] = 1;
Top[i] = i;
}
int curr_idx = 1;
vector<int> rem, add;
for (int i = 1; i <= m; i++) {
if (ans[i]) continue;
auto [u, v] = edge[i];
int lca = getLCA(u, v);
/// All edge not visited
int tick = 0;
while (true) {
u = find_set(u);
rem.push_back(u);
if (depth[Top[u]] <= depth[lca]) break;
add.push_back(belong[Top[u]]);
u = par[Top[u]];
}
while (true) {
v = find_set(v);
rem.push_back(v);
if (depth[Top[v]] <= depth[lca]) break;
add.push_back(belong[Top[v]]);
v = par[Top[v]];
}
if (add.size()) {
sort(add.begin(), add.end());
for (auto x: add)
ans[x] = curr_idx++;
}
for (auto x: rem)
union_set(x, u);
rem.clear(); add.clear();
if (!ask[i]) ans[i] = curr_idx++;
}
for (int i = 1; i <= m; i++)
cout << ans[i] << ' ';
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |