QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#189036 | #6861. Counter Strike | jrjyy | AC ✓ | 413ms | 40704kb | C++20 | 4.8kb | 2023-09-26 19:41:59 | 2023-09-26 19:41:59 |
Judging History
answer
#include <bits/stdc++.h>
using i64 = long long;
struct DSU {
std::vector<int> fa, sz;
DSU(int n = 0) { init(n); }
void init(int n) {
fa.resize(n), std::iota(fa.begin(), fa.end(), 0);
sz.assign(n, 1);
}
int find(int x) {
while (x != fa[x]) x = fa[x] = fa[fa[x]];
return x;
}
bool same(int x, int y) { return find(x) == find(y); }
bool merge(int x, int y) {
if ((x = find(x)) == (y = find(y))) return false;
return sz[x] += sz[y], fa[y] = x, true;
}
int size(int x) { return sz[find(x)]; }
};
struct BlockCutTree {
int n;
std::vector<std::vector<int>> adj;
std::vector<int> dfn, low, stk;
int cur, cnt;
std::vector<std::pair<int, int>> edges;
BlockCutTree(int n_ = 0) {
init(n_);
}
void init(int n_) {
n = n_;
adj.assign(n, {});
dfn.assign(n, -1);
low.resize(n);
stk.clear();
cur = cnt = 0;
edges.clear();
}
void addEdge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
}
void dfs(int u) {
dfn[u] = low[u] = cur++;
stk.push_back(u);
for (auto v : adj[u]) {
if (dfn[v] == -1) {
dfs(v);
low[u] = std::min(low[u], low[v]);
if (low[v] == dfn[u]) {
for (int x = -1; x != v; stk.pop_back()) {
x = stk.back();
edges.emplace_back(n + cnt, x);
}
edges.emplace_back(u, n + cnt++);
}
} else {
low[u] = std::min(low[u], dfn[v]);
}
}
}
std::pair<int, std::vector<std::pair<int, int>>> work(int rt = 0) {
dfs(rt);
return {cnt, edges};
}
};
void solve() {
int n, m, k;
std::cin >> n >> m >> k;
std::vector<std::vector<int>> adj(n);
for (int i = 0; i < m; ++i) {
int u, v;
std::cin >> u >> v;
--u, --v;
adj[u].push_back(v);
adj[v].push_back(u);
}
std::vector<int> a(k);
for (auto &u : a) {
std::cin >> u;
--u;
}
std::vector<bool> vis;
DSU dsu(n);
std::vector<std::vector<int>> s(n);
int dcnt = -1;
auto work = [&](int del) {
vis.assign(n, true);
dsu.init(n);
s.assign(n, {});
dcnt = 0;
for (auto u : a) {
vis[u] = false;
s[u] = {u};
}
if (del != -1) {
vis[del] = false;
}
auto merge = [&](int u, int v) {
if (!vis[u] || !vis[v]) {
return;
}
u = dsu.find(u), v = dsu.find(v);
if (u == v) {
return;
}
dcnt -= (s[u].size() >= 2) + (s[v].size() >= 2);
s[u].insert(s[u].end(), s[v].begin(), s[v].end());
dcnt += (s[u].size() >= 2);
dsu.merge(u, v);
};
for (int u = 0; u < n; ++u) {
for (auto v : adj[u]) {
merge(u, v);
}
}
for (int i = k - 1; i >= 0; --i) {
int u = a[i];
if (u == del) {
continue;
}
vis[u] = true;
for (auto v : adj[u]) {
merge(u, v);
}
if (s[u].size() >= 3 || dcnt >= 1 + (del == -1)) {
return i;
}
}
return -1;
};
int ans = work(-1), x = a[ans];
if (dcnt >= 2 || ans == -1) {
std::cout << ans + 1 << "\n";
return;
}
BlockCutTree g(n);
for (int u = 0; u < n; ++u) {
for (auto v : adj[u]) {
if (vis[u] && vis[v] && u < v) {
g.addEdge(u, v);
}
}
}
auto [cnt, edges] = g.work(x);
std::vector<std::vector<int>> e(n + cnt);
for (auto [u, v] : edges) {
e[u].push_back(v);
e[v].push_back(u);
}
int y = s[x][1], z = s[x][2], del = -1;
auto dfs = [&](auto self, int u, int fa) -> int {
int c = u == y || u == z;
for (auto v : e[u]) {
if (v == fa) {
continue;
}
c += self(self, v, u);
}
if (c == 2 && del == -1) {
del = u;
}
return c;
};
dfs(dfs, x, -1);
if (del >= n) {
std::cout << ans + 1 << "\n";
return;
}
ans = std::min(ans, work(del));
std::cout << ans + 1 << "\n";
}
int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 413ms
memory: 40704kb
input:
4446 21 23 21 21 20 19 10 6 11 9 21 18 9 14 1 18 11 14 2 19 15 17 11 6 2 19 17 3 16 1 7 5 11 17 4 10 20 13 16 13 3 13 8 9 11 12 13 12 18 12 3 13 4 10 11 6 1 14 9 15 21 8 19 18 5 16 17 7 20 2 24 28 24 19 15 2 11 20 18 19 17 8 6 3 10 21 18 22 6 21 10 14 6 14 7 5 19 2 23 5 10 1 11 12 20 13 16 24 3 10 9...
output:
12 19 8 4 5 2 15 12 12 18 13 13 4 6 10 11 7 13 15 12 11 0 5 0 11 10 3 0 12 1 15 15 12 11 11 7 13 7 15 12 8 14 4 6 12 11 0 17 18 16 1 1 15 11 6 10 12 18 11 3 2 11 9 12 0 5 16 3 11 15 11 14 12 14 0 15 12 16 9 14 15 10 1 18 11 4 3 0 8 11 11 11 19 16 12 13 19 0 7 11 15 5 14 0 14 4 13 2 8 12 12 0 17 16 1...
result:
ok 4446 lines