QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#463590#8253. Very Important Edge36champTL 0ms0kbC++205.9kb2024-07-05 01:51:062024-07-05 01:51:06

Judging History

This is the latest submission verdict.

  • [2024-07-05 01:51:06]
  • Judged
  • Verdict: TL
  • Time: 0ms
  • Memory: 0kb
  • [2024-07-05 01:51:06]
  • Submitted

answer

#include <bits/stdc++.h>
#define ll long long
#define pb push_back

using namespace std;

const ll INF = 1LL << 62;
int n, m;

class DSU{
    public:
        vector<int> parent, rnk;

        DSU(int n) {
            parent = vector<int>(n, 0);
            rnk = parent;
            for(int i=0; i<n; i++) make_set(i);
        }

        void log()
        {
            for(int x: parent) cout << x << " ";
            cout << "\n";
        }

        void make_set(int v) {
            parent[v] = v;
            rnk[v] = 0;
        }

        int find_set(int v) {
            if(v < 0) return v;
            if (v == parent[v])
                return v;
            parent[v] = find_set(parent[v]);
            return parent[v];
        }

        void union_sets(int a, int b) {
            if(a<0 || b<0) return;
            a = find_set(a);
            b = find_set(b);
            if (a != b) {
                if (rnk[a] < rnk[b])
                    swap(a, b);
                parent[b] = a;
                if (rnk[a] == rnk[b])
                {
                    rnk[a]++;
                }
            }
        }
};

class segTree{
    public:
        vector<ll> t;

        segTree(int n)
        {
            t = vector<ll>(4 * n, INF);
        }

        void build(vector<ll> &a, ll v, ll tl, ll tr) {
            if (tl == tr) {
                t[v] = a[tl];
            } else {
                ll tm = (tl + tr) / 2;
                build(a, v*2, tl, tm);
                build(a, v*2+1, tm+1, tr);
                t[v] = t[v*2] + t[v*2+1];
            }
        }

        ll min(ll v, ll tl, ll tr, ll l, ll r) {
            if (l > r)
                return INF;
            if (l == tl && r == tr) {
                return t[v];
            }
            ll tm = (tl + tr) / 2;
            return std::min(min(v*2, tl, tm, l, std::min(r, tm))
                   , min(v*2+1, tm+1, tr, max(l, tm+1), r));
        }

        void update(ll v, ll tl, ll tr, ll pos, ll new_val) {
            if (tl == tr) {
                t[v] = new_val;
            } else {
                ll tm = (tl + tr) / 2;
                if (pos <= tm)
                    update(v*2, tl, tm, pos, new_val);
                else
                    update(v*2+1, tm+1, tr, pos, new_val);
                t[v] = std::min(t[v*2], t[v*2+1]);
            }
        }
};


void dfs(int p, vector<vector<vector<ll>>> &adj, vector<vector<int>> &up, vector<int> &depth, vector<ll> &v)
{
    for(vector<ll> edge: adj[p])
    {
        ll c = edge[0], val = edge[1];

        if(c == up[p][0]) continue;

        v[c] = val;
        depth[c] = depth[p] + 1;
        up[c][0] = p;
        for(int i=1; i<=19; i++) up[c][i] = up[up[c][i-1]][i-1];
        dfs(c, adj, up, depth, v);
    }
}

int lca(vector<vector<int>> &up, int u, int v, int d_u, int d_v)
{
    if(d_v < d_u)
    {
        swap(u, v);
        swap(d_u, d_v);
    }

    cerr << "LCA " << u << " " << d_u << " " << v << " " << d_v << " -> ";

    for(int i=19; i>=0; i--)
    {
        if(d_u + (1 << i) <= d_v)
        {
            v = up[v][i];
            d_v -= 1 << i;
        }
    }

    cerr << v << " " << d_v << " = ";

    if(u == v) return u;

    for(int i=19; i>=0; i--)
    {
        if(up[u][i] != up[v][i])
        {
            u = up[u][i];
            v = up[v][i];
        }
    }

    return up[u][0];
}

void dfs2(int p, int &pos, vector<vector<vector<ll>>> &adj, vector<vector<vector<ll>>> &adj2, vector<vector<int>> &up, vector<int> &left, vector<vector<int>> &del, vector<ll> &l, segTree &T, vector<int> &depth)
{
    //cout << "DFS 2 : " << p << " " << pos << "\n";

    left[p] = pos;

    for(vector<ll> edge: adj[p])
    {
        ll c = edge[0], val = edge[1];

        if(c == up[p][0]) continue;

        dfs2(c, pos, adj, adj2, up, left, del, l, T, depth);
    }

    for(vector<ll> edge: adj2[p])
    {
        ll c = edge[0], val = edge[1];

        T.update(1, 0, 2*m-2*n+1, pos, val);

        ll x = lca(up, p, c, depth[p], depth[c]);
        del[x].pb(pos);

        cerr << x << "\n";

        pos++;
    }

    for(int index: del[p])
    {
        T.update(1, 0, 2*m-2*n+1, index, INF);
    }

    for(ll x: T.t) cerr << x << " ";
    cerr << "\n";

    cerr << "FIND MIN " << left[p] << " " << pos - 1 << " = ";

    l[p] = T.min(1, 0, 2*m-2*n+1, left[p], pos - 1);

    cerr << l[p] << "\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	cin >> n >> m;

	vector<vector<ll>> edge(m, {0, 0, 0});
	vector<vector<int>> up(n + 1, vector<int>(20, 0));

	ll ans = 0;
	for(int i=0; i<m; i++) cin >> edge[i][1] >> edge[i][2] >> edge[i][0];
	sort(edge.begin(), edge.end());

	vector<vector<vector<ll>>> adj(n + 1), adj2(n + 1);
	DSU a(n + 1);
	for(int i=0; i<m; i++)
    {
        int u = edge[i][1], v = edge[i][2], c = edge[i][0];
        if(a.find_set(u) != a.find_set(v))
        {
            a.union_sets(u, v);
            ans += c;
            adj[u].pb({v, c});
            adj[v].pb({u, c});
        }
        else
        {
            adj2[u].pb({v, c});
            adj2[v].pb({u, c});
        }
    }

    vector<int> depth(n + 1, 0);
    vector<ll> val(n + 1);
    dfs(1, adj, up, depth, val);

    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<20; j++) cerr << up[i][j] << " ";
        cerr << "\n";
    }

    /*for(int x: depth) cout << x << " ";
    cout << "\n";*/

    segTree T(2*m - 2*n + 2);

    vector<int> left(n + 1);
    vector<ll> l(n + 1, INF);
    vector<vector<int>> del(n+1);
    int pos = 0;
    dfs2(1, pos, adj, adj2, up, left, del, l, T, depth);

    for(ll x: l) cerr << x << " ";

    ll M = 0;
    for(int i=2; i<=n; i++) M = max(M, l[i] - val[i]);

    cout << ans + M;
}
/*
6 8
1 2 1
1 3 2
2 4 3
2 5 4
3 6 5
4 5 6
1 5 7
2 6 8
*/

詳細信息

Test #1:

score: 0
Time Limit Exceeded

input:

1000 499500
26 715 732723
850 918 507404
276 643 372190
67 702 972051
397 777 337003
178 185 863117
61 151 943008
83 581 731622
99 501 3260
301 588 948638
17 908 147104
193 480 94512
347 415 416562
519 912 627431
70 959 86892
333 573 757685
129 197 181261
224 636 259176
335 426 567962
193 339 70097
...

output:


result: