結果
問題 | No.529 帰省ラッシュ |
ユーザー | 37zigen |
提出日時 | 2017-06-11 14:29:12 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 2,943 ms / 4,500 ms |
コード長 | 7,580 bytes |
コンパイル時間 | 2,710 ms |
コンパイル使用メモリ | 83,632 KB |
実行使用メモリ | 181,652 KB |
最終ジャッジ日時 | 2024-05-09 16:31:43 |
合計ジャッジ時間 | 37,920 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 123 ms
41,248 KB |
testcase_01 | AC | 124 ms
41,176 KB |
testcase_02 | AC | 127 ms
41,440 KB |
testcase_03 | AC | 130 ms
41,604 KB |
testcase_04 | AC | 315 ms
47,656 KB |
testcase_05 | AC | 303 ms
48,376 KB |
testcase_06 | AC | 306 ms
48,596 KB |
testcase_07 | AC | 311 ms
48,100 KB |
testcase_08 | AC | 2,618 ms
98,324 KB |
testcase_09 | AC | 2,519 ms
101,280 KB |
testcase_10 | AC | 2,938 ms
147,084 KB |
testcase_11 | AC | 2,721 ms
154,288 KB |
testcase_12 | AC | 2,268 ms
88,856 KB |
testcase_13 | AC | 2,416 ms
168,452 KB |
testcase_14 | AC | 2,244 ms
87,012 KB |
testcase_15 | AC | 2,858 ms
181,652 KB |
testcase_16 | AC | 2,943 ms
157,672 KB |
testcase_17 | AC | 2,733 ms
139,408 KB |
testcase_18 | AC | 2,647 ms
146,028 KB |
testcase_19 | AC | 2,727 ms
166,932 KB |
ソースコード
import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.PriorityQueue; import java.util.Scanner; import java.util.Set; class Main implements Runnable { public static void main(String[] args) { long t = System.currentTimeMillis(); // new Main().run(); new Thread(null, new Main(), "", Runtime.getRuntime().maxMemory()).start(); System.err.println(System.currentTimeMillis() - t); } class State { int i; int parent; int j;// 操作後g[i][j]に潜る public State(int i_, int parent_, int j_) { i = i_; parent = parent_; j = j_; } } int two_edge_connected_componets(ArrayList<Integer>[] g, int[] col) { int n = g.length; Arrays.fill(col, -1); int cols = 0; int[] low = new int[n]; int[] ord = new int[n]; boolean[] marked = new boolean[n]; Arrays.fill(low, -1); Arrays.fill(ord, -1); int order = 0; ArrayDeque<State> stk = new ArrayDeque<>(); ArrayDeque<Integer> pnd = new ArrayDeque<>(); for (int ii = 0; ii < n; ++ii) { if (ord[ii] == -1) { stk.add(new State(ii, -1, 0)); } while (!stk.isEmpty()) { State s = stk.pollFirst(); if (ord[s.i] == -1) { low[s.i] = (ord[s.i] = order++); pnd.addFirst(s.i); } if (s.j > 0 && s.parent != g[s.i].get(s.j - 1) && !marked[g[s.i].get(s.j - 1)]) { low[s.i] = Math.min(low[s.i], low[g[s.i].get(s.j - 1)]); } if (s.j == g[s.i].size() && low[s.i] == ord[s.i]) { while (true) { int v = pnd.pollFirst(); col[v] = cols; marked[v] = true; if (v == s.i) break; } ++cols; } if (s.j == g[s.i].size()) continue; int v = g[s.i].get(s.j); stk.addFirst(new State(s.i, s.parent, s.j + 1)); if (ord[v] == -1) { stk.addFirst(new State(v, s.i, 0)); } else if (v != s.parent && !marked[v]) { low[s.i] = Math.min(low[s.i], low[v]); } } } return cols; } @SuppressWarnings("unchecked") public void run() { Scanner sc = new Scanner(System.in); PrintWriter pw = new PrintWriter(System.out); int n = sc.nextInt(); int m = sc.nextInt(); int q = sc.nextInt(); ArrayList<Integer>[] g = new ArrayList[n]; for (int i = 0; i < n; ++i) { g[i] = new ArrayList<>(); } for (int i = 0; i < m; ++i) { int a = sc.nextInt() - 1; int b = sc.nextInt() - 1; g[a].add(b); g[b].add(a); } int[] col = new int[n]; int cols = two_edge_connected_componets(g, col); ArrayList<Integer>[] h = new ArrayList[cols]; PriorityQueue<Long>[] w = new PriorityQueue[cols]; for (int i = 0; i < cols; ++i) { w[i] = new PriorityQueue<>(new Comparator<Long>() { @Override public int compare(Long o1, Long o2) { return -Long.compare(o1, o2); } }); } for (int i = 0; i < cols; ++i) { w[i].add(-1L); } for (int i = 0; i < cols; ++i) { h[i] = new ArrayList<>(); } Set<Integer>[] mp = new Set[cols]; for (int i = 0; i < cols; ++i) { mp[i] = new HashSet<>(); } for (int i = 0; i < n; ++i) { for (int j : g[i]) { int a = col[i]; int b = col[j]; if (a == b) continue; if (mp[a].contains(b)) continue; h[a].add(b); h[b].add(a); mp[a].add(b); mp[b].add(a); } } HLDecomposition hl = new HLDecomposition(cols); for (int i = 0; i < cols; ++i) { for (int j : h[i]) { if (i > j) { hl.ae(i, j); } } } hl.pre(); SegmentTree st = new SegmentTree(cols); int[] ref = new int[cols]; Arrays.fill(ref, -1); for (int i = 0; i < cols; ++i) { ref[hl.id[i]] = i; } while (q-- > 0) { int t = sc.nextInt(); if (t == 1) {// modification query int u = sc.nextInt() - 1; long v = sc.nextInt(); u = col[u]; w[u].add(v); st.setVal(hl.id[u], w[u].peek()); } else {// ouput query int src = sc.nextInt() - 1; int dst = sc.nextInt() - 1; src = col[src]; dst = col[dst]; long v = output(src, dst, hl, st); pw.println(v == -1 ? v : v >> 32); if (v != -1) { w[ref[(int) v]].poll(); st.setVal((int) v, w[ref[(int) v]].peek()); } } } pw.close(); } long output(int a, int b, HLDecomposition hl, SegmentTree st) { long ea = -1; long eb = -1; while (hl.head[a] != hl.head[b]) { if (hl.depth[hl.head[a]] < hl.depth[hl.head[b]]) { int tmp = a; a = b; b = tmp; long tmp_e = ea; ea = eb; eb = tmp_e; } ea = merge(st.query(hl.id[hl.head[a]], hl.id[a] + 1), ea); a = hl.parent[hl.head[a]]; } if (hl.depth[a] < hl.depth[b]) { int tmp = a; a = b; b = tmp; long tmp_e = ea; ea = eb; eb = tmp_e; } return merge(eb, merge(st.query(hl.id[b], hl.id[a] + 1), ea)); } long merge(long a, long b) { return Math.max(a, b); } class SegmentTree { int n; long[] Vs; public SegmentTree(int n_) { n = 1; while (n < n_) { n *= 2; } Vs = new long[2 * n - 1]; for (int i = 0; i < n; ++i) { Vs[i + n - 1] = -1; } for (int i = n - 2; i >= 0; --i) { Vs[i] = merge(Vs[2 * i + 1], Vs[2 * i + 2]); } } void setVal(int k, long val) { k += n - 1; if (val != -1) Vs[k] = val << 32 | (k - (n - 1)); else Vs[k] = -1; while (k > 0) { k = (k - 1) / 2; Vs[k] = merge(Vs[2 * k + 1], Vs[2 * k + 2]); } } // [a,b),[l,r) long query(int a, int b) { return query(a, b, 0, n, 0); } long query(int a, int b, int l, int r, int k) { if (b <= l || r <= a) { return -1L; } if (a <= l && r <= b) { return Vs[k]; } else { long vl = query(a, b, l, (l + r) / 2, 2 * k + 1); long vr = query(a, b, (l + r) / 2, r, 2 * k + 2); return merge(vl, vr); } } } class HLDecomposition { int n; int[] depth; int[] head; int[] heavy; int[] parent; int[] sz; ArrayList<Integer>[] g; int[] id; @SuppressWarnings("unchecked") public HLDecomposition(int n) { this.n = n; depth = new int[n]; head = new int[n]; heavy = new int[n]; parent = new int[n]; id = new int[n]; sz = new int[n]; g = new ArrayList[n]; for (int i = 0; i < n; ++i) { g[i] = new ArrayList<>(); } Arrays.fill(head, -1); Arrays.fill(id, -1); Arrays.fill(parent, -1); Arrays.fill(heavy, -1); } void ae(int a, int b) { g[a].add(b); g[b].add(a); } void pre() { dfs(0, -1); bfs(); } void bfs() { ArrayDeque<Integer> pend = new ArrayDeque<>(); int gen = 0; pend.add(0); while (!pend.isEmpty()) { int v = pend.pollFirst(); int top = v; for (; v != -1; v = heavy[v]) { id[v] = gen++; head[v] = top; for (int d : g[v]) { if (d == parent[v] || d == heavy[v]) { continue; } pend.add(d); } } } } int lca(int u, int v) { if (head[u] != head[v]) { if (depth[head[u]] < depth[head[v]]) { int tmp = u; u = v; v = tmp; } return lca(parent[head[u]], v); } else { if (depth[u] > depth[v]) { int tmp = u; u = v; v = tmp; } return u; } } int dfs(int c, int p) { parent[c] = p; int s = 1; int to = -1; for (int d : g[c]) { if (d == p) continue; depth[d] = depth[c] + 1; s += dfs(d, c); if (to == -1 || sz[d] > sz[to]) { to = d; } } sz[c] = s; // -- for (int d : g[c]) if (sz[d] * 2 >= sz[c]) { heavy[c] = d; } // -- heavy[c] = to; return s; } } static void tr(Object... objects) { System.out.println(Arrays.deepToString(objects)); } }