Submission #494507

#TimeUsernameProblemLanguageResultExecution timeMemory
494507blueRigged Roads (NOI19_riggedroads)C++17
100 / 100
425 ms67628 KiB
#include <iostream> #include <vector> #include <algorithm> using namespace std; const int mx = 300'000; const int lg = 18; using vi = vector<int>; using pii = pair<int, int>; int N, E; vi A(1+mx), B(1+mx); vi good(1+mx, 0); vector<pii> edge[1+mx]; vi depth(1+mx, 1); int anc[1+mx][1+lg]; vi par_edge(1+mx); void dfs(int u, int p) { for(pii h: edge[u]) { int v = h.first; int e = h.second; if(v == p) continue; par_edge[v] = e; anc[v][0] = u; depth[v] = 1 + depth[u]; dfs(v, u); } } int lca(int u, int v) { if(depth[u] > depth[v]) swap(u, v); for(int e = lg; e >= 0; e--) { if(depth[v] - (1 << e) < depth[u]) continue; v = anc[v][e]; } if(u == v) return u; for(int e = lg; e >= 0; e--) { if(anc[u][e] != anc[v][e]) { u = anc[u][e]; v = anc[v][e]; } } return anc[u][0]; } struct ds { vi par = vi(1+mx); vi st = vi(1+mx, 1); vi rt = vi(1+mx); ds() { for(int i = 1; i <= N; i++) par[i] = rt[i] = i; } int root(int u) { if(par[u] == u) return u; else { par[u] = root(par[u]); return par[u]; } } void join(int u, int v) { u = root(u); v = root(v); if(u == v) return; if(st[u] < st[v]) swap(u, v); par[v] = u; st[u] += st[v]; rt[u] = ((depth[rt[u]] < depth[rt[v]]) ? rt[u] : rt[v]); } bool connected(int u, int v) { return root(u) == root(v); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N >> E; for(int j = 1; j <= E; j++) { cin >> A[j] >> B[j]; } for(int i = 1; i <= N-1; i++) { int g; cin >> g; good[g] = 1; edge[A[g]].push_back({B[g], g}); edge[B[g]].push_back({A[g], g}); } // cerr << "done\n"; depth[0] = 0; anc[0][0] = 0; anc[1][0] = 0; dfs(1, 0); for(int e = 1; e <= lg; e++) { for(int u = 0; u <= N; u++) { anc[u][e] = anc[ anc[u][e-1] ][e-1]; } } vi W(1+E, 0); int curr_w = 0; ds DSU; // cerr << "pre done\n"; for(int e = 1; e <= E; e++) { // cerr << "e = " << e << '\n'; if(W[e]) continue; if(good[e]) W[e] = ++curr_w; else { vi new_edges; int L = lca(A[e], B[e]); // cerr << "lca found\n"; int a = A[e], b = B[e]; while(DSU.root(a) != DSU.root(L)) { // cerr << a << '\n'; a = DSU.root(a); new_edges.push_back(par_edge[DSU.rt[a]]); DSU.join(a, anc[DSU.rt[a]][0]); } // cerr << "w1 done\n"; while(DSU.root(b) != DSU.root(L)) { // cerr << "" b = DSU.root(b); new_edges.push_back(par_edge[DSU.rt[b]]); DSU.join(b, anc[DSU.rt[b]][0]); } // cerr << "w2 done\n"; sort(new_edges.begin(), new_edges.end()); for(int q: new_edges) if(!W[q]) W[q] = ++curr_w; W[e] = ++curr_w; } } for(int i = 1; i <= E; i++) cout << W[i] << ' '; cout << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...