QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#646036 | #6402. MEXimum Spanning Tree | crimsonsunset# | TL | 0ms | 3780kb | C++20 | 4.4kb | 2024-10-16 21:01:37 | 2024-10-16 21:01:37 |
Judging History
answer
#pragma GCC optimize("")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define int ll
#define ff first
#define ss second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
constexpr int INF = 1e18;
struct edge {
int u, v, c;
};
int idi_naxui(vector<edge> &e, int n) {
int m = e.size();
vector<int> j;
while (true) {
vector<int> x1, x2, color(n + 1, 0);
for (int i: j)
++color[e[i].c];
vector<bool> used(m, false);
for (int i: j)
used[i] = true;
vector<vector<int>> gr(m);
for (int i = 0; i < j.size(); ++i)
for (int k = 0; k < m; ++k)
if (!used[k]) {
if (color[e[k].c] == 0)
gr[j[i]].push_back(k);
else if (e[k].c == e[j[i]].c)
gr[j[i]].push_back(k);
}
for (int k = 0; k < m; ++k)
if (!used[k])
if (color[e[k].c] == 0)
x1.push_back(k);
vector<int> comp(n, -1);
int cnt = 0;
vector<vector<int>> trees(n);
auto dfs = [&](auto dfs, int v, int p, vector<int> &c) -> void {
c[v] = cnt;
for (int u: trees[v])
if (u != p)
dfs(dfs, u, v, c);
};
for (int q = 0; q < j.size(); ++q) {
trees[e[j[q]].u].push_back(e[j[q]].v);
trees[e[j[q]].v].push_back(e[j[q]].u);
}
for (int i = 0; i < n; ++i)
if (comp[i] == -1) {
dfs(dfs, i, -1, comp);
++cnt;
}
for (int i = 0; i < j.size(); ++i) {
for (int q = 0; q < n; ++q)
trees[q].clear();
for (int q = 0; q < j.size(); ++q)
if (q != i) {
trees[e[j[q]].u].push_back(e[j[q]].v);
trees[e[j[q]].v].push_back(e[j[q]].u);
}
cnt = 0;
vector<int> cd(n, -1);
for (int k = 0; k < n; ++k)
if (cd[k] == -1) {
dfs(dfs, k, -1, cd);
++cnt;
}
for (int k = 0; k < m; ++k)
if (!used[k]) {
if (comp[e[k].u] != comp[e[k].v])
gr[k].push_back(j[i]);
else if (cd[e[k].u] != cd[e[k].v])
gr[k].push_back(j[i]);
}
}
for (int k = 0; k < m; ++k)
if (!used[k])
if (comp[e[k].u] != comp[e[k].v])
x2.push_back(k);
if (x1.empty() || x2.empty()) {
break;
}
vector<int> dist(m, INF), prev(m, -1);
deque<int> bfs;
for (int i = 0; i < x1.size(); ++i)
bfs.push_back(x1[i]), dist[x1[i]] = 0;
while (!bfs.empty()) {
int v = bfs.front();
bfs.pop_front();
for (int u: gr[v])
if (dist[v] + 1 < dist[u]) {
dist[u] = dist[v] + 1;
bfs.push_back(u);
prev[u] = v;
}
}
int ind = x2[0];
for (int i = 1; i < x2.size(); ++i)
if (dist[x2[i]] < dist[ind])
ind = x2[i];
if (dist[ind] == INF)
break;
vector<int> rebuild(m, 0);
for (int i: j)
rebuild[i] ^= 1;
int last = ind;
while (last != -1) {
rebuild[last] ^= 1;
last = prev[last];
}
vector<int> new_j;
for (int i = 0; i < m; ++i)
if (rebuild[i])
new_j.push_back(i);
j = new_j;
}
return j.size();
}
void solve() {
int n, m;
cin >> n >> m;
vector<edge> e(m);
for (auto &i: e)
cin >> i.u >> i.v >> i.c, --i.u, --i.v;
int l = 0, r = m + 1;
while (r - l > 1) {
int mid = (l + r) / 2;
vector<edge> ee;
for (auto i : e)
if (i.c < mid)
ee.push_back(i);
if (idi_naxui(ee, n) == mid)
l = mid;
else
r = mid;
}
cout << l;
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t = 1;
// cin >> t;
while (t--) solve();
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3780kb
input:
4 4 1 2 0 2 3 1 1 3 1 3 4 2
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: -100
Time Limit Exceeded
input:
1000 1000 647 790 6 91 461 435 90 72 74 403 81 240 893 925 395 817 345 136 88 71 821 831 962 53 164 270 298 14 550 317 99 580 81 26 477 488 977 474 861 413 483 167 872 675 17 819 327 449 594 242 68 381 983 319 867 582 358 869 225 669 274 352 392 40 388 998 246 477 44 508 979 286 483 776 71 580 438 6...