QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#646036#6402. MEXimum Spanning Treecrimsonsunset#TL 0ms3780kbC++204.4kb2024-10-16 21:01:372024-10-16 21:01:37

Judging History

你现在查看的是最新测评结果

  • [2024-10-16 21:01:37]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3780kb
  • [2024-10-16 21:01:37]
  • 提交

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...

output:


result: