結果
| 問題 |
No.529 帰省ラッシュ
|
| コンテスト | |
| ユーザー |
penguinshunya
|
| 提出日時 | 2019-07-10 13:39:29 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,660 bytes |
| コンパイル時間 | 3,097 ms |
| コンパイル使用メモリ | 241,984 KB |
| 最終ジャッジ日時 | 2025-01-07 06:32:21 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 1 WA * 17 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
struct UnWeightedGraph {
struct Edge {
int to;
Edge(int to) : to(to) {}
};
vector<vector<Edge>> edges;
int n;
UnWeightedGraph(int n) : n(n) {
edges.assign(n, vector<Edge>());
}
void add_edge(int v, int u) {
edges[v].emplace_back(u);
}
vector<Edge> &operator[](int x) {
return edges[x];
}
};
template <typename Graph>
struct LowLink {
using A = vector<int>;
using B = vector<pair<int, int>>;
Graph &g;
int n;
vector<bool> seen;
vector<int> ord, low;
A articulation;
B bridge;
LowLink(Graph &g) : g(g), n(g.n) {}
void dfs(int v, int p, int &k) {
seen[v] = true;
ord[v] = k++;
low[v] = ord[v];
bool is = false;
int cnt = 0;
for (auto e : g[v]) {
int u = e.to;
if (seen[u]) {
if (u != p) low[v] = min(low[v], ord[u]);
continue;
}
cnt++;
dfs(u, v, k);
low[v] = min(low[v], low[u]);
if (p != -1 && ord[v] <= low[u]) is = true;
if (ord[v] < low[u]) bridge.emplace_back(minmax(v, u));
}
if (p == -1 && cnt > 1) is = true;
if (is) articulation.push_back(v);
}
pair<A, B> build() {
seen.assign(n, false);
ord.assign(n, 0);
low.assign(n, 0);
articulation.clear();
bridge.clear();
int k = 0;
dfs(0, -1, k);
return pair<A, B>(articulation, bridge);
}
pair<A, B> operator()() {
return build();
}
};
template <typename Graph>
struct TwoEdgeConnectedComponent {
using B = vector<pair<int, int>>;
Graph &g;
int n;
vector<bool> seen;
vector<int> group;
set<pair<int, int>> b;
TwoEdgeConnectedComponent(Graph &g) : g(g), n(g.n), group(n) {}
void dfs(int v, int p, int k) {
seen[v] = true;
group[v] = k;
for (auto e : g[v]) {
int u = e.to;
if (u == p) continue;
if (seen[u]) continue;
if (b.find(minmax(v, u)) != b.end()) continue;
dfs(u, v, k);
}
}
vector<int> decompose(B bridge) {
seen.assign(n, false);
b.clear();
b.insert(bridge.begin(), bridge.end());
int k = 0;
for (int i = 0; i < n; i++) {
if (seen[i]) continue;
dfs(i, -1, k++);
}
return group;
}
vector<int> operator()(B bridge) {
return decompose(bridge);
}
};
template <typename T>
struct SegmentTree {
using F = function<T(T, T)>;
vector<T> v;
F f;
T e;
int n;
SegmentTree(int size, F f, T e) : f(f), e(e) {
n = 1;
while (n < size) n <<= 1;
v.resize(n * 2, e);
}
void set(int k, T x) {
v[k + n] = x;
}
void build() {
for (int i = n - 1; i > 0; i--) {
v[i] = f(v[i * 2 + 0], v[i * 2 + 1]);
}
}
void update(int k, T x) {
v[k += n] = x;
while (k >>= 1) v[k] = f(v[k * 2 + 0], v[k * 2 + 1]);
}
T query(int a, int b) {
T l = e, r = e;
for (a += n, b += n; a < b; a >>= 1, b >>= 1) {
if (a & 1) l = f(l, v[a++]);
if (b & 1) r = f(v[--b], r);
}
return f(l, r);
}
};
template <typename Graph>
struct HeavyLightDecomposition {
Graph &g;
int n;
vector<int> par;
vector<int> next;
vector<int> vid;
vector<int> head;
HeavyLightDecomposition(Graph &g)
: g(g), n(g.n), par(n), next(n, -1), vid(n), head(n) {}
int dfs(int v = 0, int p = -1) {
par[v] = p;
int mx = 0, ret = 1;
for (auto e : g[v]) {
if (e.to == p) continue;
int r = dfs(e.to, v);
ret += r;
if (mx < r) mx = r, next[v] = e.to;
}
return ret;
}
void bfs(int r = 0) {
int k = 0;
queue<int> q;
q.emplace(r);
while (!q.empty()) {
auto h = q.front(); q.pop();
for (int v = h; v != -1; v = next[v]) {
vid[v] = k++;
head[v] = h;
for (auto e : g[v]) {
if (e.to == par[v] || e.to == next[v]) continue;
q.emplace(e.to);
}
}
}
}
vector<int> build() {
dfs();
bfs();
return vid;
}
void for_each(int v, int u, const function<void(int, int)> &f) {
while (true) {
if (vid[u] > vid[v]) swap(v, u);
f(max(vid[head[v]], vid[u]), vid[v]);
if (head[u] != head[v]) v = par[head[v]];
else break;
}
}
};
int main() {
int N, M, Q; cin >> N >> M >> Q;
auto graph = UnWeightedGraph(N);
for (int i = 0; i < M; i++) {
int v, u; cin >> v >> u;
v--, u--;
graph.add_edge(v, u);
graph.add_edge(u, v);
}
auto low = LowLink<UnWeightedGraph>(graph);
auto two = TwoEdgeConnectedComponent<UnWeightedGraph>(graph);
auto lll = low.build();
auto dict = two.decompose(lll.second);
int V = *max_element(dict.begin(), dict.end()) + 1;
auto hraph = UnWeightedGraph(V);
for (int i = 0; i < N; i++) {
for (auto e : graph[i]) {
if (dict[i] == dict[e.to]) continue;
hraph.add_edge(dict[i], dict[e.to]);
}
}
auto hld = HeavyLightDecomposition<UnWeightedGraph>(hraph);
auto vid = hld.build();
auto seg = SegmentTree<long long>(V, [](long long a, long long b) {
return max(a, b);
}, -1ll);
vector<priority_queue<int>> q(V);
map<int, int> ma;
for (int i = 0; i < Q; i++) {
int n; cin >> n;
if (n == 1) {
int u, w; cin >> u >> w;
u--;
u = vid[dict[u]];
seg.update(u, w);
ma[w] = u;
q[u].emplace(w);
} else {
int s, t; cin >> s >> t;
s--, t--;
long long ans = -1;
s = vid[dict[s]], t = vid[dict[t]];
hld.for_each(s, t, [&](int v, int u) {
ans = max(ans, seg.query(v, u + 1));
});
cout << ans << '\n';
if (ans != -1) {
int u = ma[ans];
q[u].pop();
seg.update(u, q[u].size() > 0 ? q[u].top() : -1);
}
}
}
return 0;
}
penguinshunya