結果
問題 |
No.3200 Sinking Islands
|
ユーザー |
![]() |
提出日時 | 2025-07-09 09:25:36 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,010 bytes |
コンパイル時間 | 2,443 ms |
コンパイル使用メモリ | 223,660 KB |
実行使用メモリ | 30,172 KB |
最終ジャッジ日時 | 2025-07-09 09:25:44 |
合計ジャッジ時間 | 8,041 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 2 TLE * 1 -- * 17 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; class UnionFind { private: vector<int> _parents; vector<int> _size; int _vertexCount; public: UnionFind(int n) { _vertexCount = n; _parents.resize(n); _size.resize(n); for (int i = 0; i < n; i++) { _size[i] = 1; _parents[i] = i; } } int Root(int x) { if (_parents[x] == x) return x; return _parents[x] = Root(_parents[x]); } int Size(int x) { return _size[Root(x)]; } void Unite(int x, int y) { int rootX = Root(x); int rootY = Root(y); if (rootX == rootY) return; int from = rootX; int to = rootY; if (_size[from] > _size[to]) { swap(from, to); } _size[to] += _size[from]; _parents[from] = to; } vector<int> Find(int x) { int root = Root(x); vector<int> set; for (int i = 0; i < _vertexCount; i++) { if (Root(i) == root) { set.push_back(i); } } return set; } unordered_map<int, vector<int>> FindAll() { unordered_map<int, vector<int>> sets; for (int i = 0; i < _vertexCount; i++) { int root = Root(i); if (sets.find(root) != sets.end()) { sets[root].push_back(i); } else { sets.emplace(root, vector<int>()); sets[root].push_back(i); } } return sets; } bool Same(int x, int y) { int rootX = Root(x); int rootY = Root(y); return rootX == rootY; } void Clear() { for (int i = 0; i < _vertexCount; i++) { _parents[i] = i; _size[i] = 1; } } int VertexCount() { return _vertexCount; } }; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int N, M; cin >> N >> M; assert(2 <= N && N <= 200000); assert(1 <= M && M <= 200000); vector<pair<int, int>> edges; vector<vector<int>> g(N, vector<int>()); for (int i = 0; i < M; i++) { int u, v; cin >> u >> v; assert(1 <= u && u <= N); assert(1 <= v && v <= N); assert(u != v); u--; v--; if (u > v) { swap(u, v); } edges.emplace_back(u, v); g[u].push_back(v); g[v].push_back(u); } for (int i = 0; i < N; i++) { sort(g[i].begin(), g[i].end()); } int Q; cin >> Q; assert(1 <= Q && Q <= 200000); vector<int> A(Q); set<int> setA; for (int i = 0; i < Q; i++) { cin >> A[i]; assert(1 <= A[i] && A[i] <= M); A[i]--; setA.insert(A[i]); } assert(setA.size() == Q); ll cur = 0; queue<int> q; vector<ll> sizes; vector<bool> seen(N); for (int i = 0; i < N; i++) { if(seen[i]) continue; int s = 0; q.push(i); while (!q.empty()) { int n = q.front(); q.pop(); if (seen[n]) continue; seen[n] = true; s++; for (int p : g[n]) { q.push(p); } } sizes.push_back(s); } { ll left = sizes[0]; for (int i = 1; i < sizes.size(); i++) { cur += left * sizes[i]; left += sizes[i]; } } for (int i = 0; i < Q; i++) { int u = edges[A[i]].first; int v = edges[A[i]].second; { int t = lower_bound(g[u].begin(), g[u].end(), v) - g[u].begin(); swap(g[u][t], g[u][g[u].size() - 1]); g[u].pop_back(); } { int t = lower_bound(g[v].begin(), g[v].end(), u) - g[v].begin(); swap(g[v][t], g[v][g[v].size() - 1]); g[v].pop_back(); } ll a = 0, b = 0; bool invalid = false; bool f = seen[u]; q.push(u); while (!q.empty()) { int n = q.front(); q.pop(); if (seen[n] == !f) continue; if (n == v) invalid = true; seen[n] = !f; a++; for (int p : g[n]) { q.push(p); } } f = seen[v]; q.push(v); while (!q.empty()) { int n = q.front(); q.pop(); if (seen[n] == !f) continue; seen[n] = !f; b++; for (int p : g[n]) { q.push(p); } } if (!invalid) cur += a * b; cout << cur << endl; } }