G. Omg Graph

链接

题目链接

思路

最小生成树模版。 易错点:
  1. 可能有多个不同的联通子图,例如1和n号点在a子图中但是其他子图也有对应的min max数据,所以建议用\(minx[N] , maxx[N]\)的方式记录,其中识别符由find_s这个函数给出。
  2. 需要用到所有的边,在用完之后才能确定,所以采用全局的记录有联通时的最小值。

代码

#define _CRT_SECURE_NO_WARNINGS 

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define tin long long
#define itn long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N = 2e5 + 10;
int n, m;
struct edge {
    itn fr, to, val;
    edge(int fr, int to, int val) {
        this->fr = fr;
        this->to = to;
        this->val = val;
    }
    bool operator<(edge x)const {
        return val > x.val;
    }
};
priority_queue<edge>pq;
int s[N],minx[N],maxx[N];
int find_s(int i) {
    return s[i] = (s[i] == i) ? s[i] : find_s(s[i]);
}
void merge_s(int a, int b) {
    int x = find_s(a), y = find_s(b);
    s[x] = s[y];
    return;
}
void solve()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)s[i] = i ,minx[i]=LLONG_MAX ,maxx[i]=0;
    for (itn i = 1; i <= m; i++) {
        int a, b, x; cin >> a >> b >> x;
        pq.push(edge(a, b, x));
    }
    itn ans = LLONG_MAX;
    while (!pq.empty()) {
        int minn = LLONG_MAX, maxn = 0;
        edge now = pq.top();
        pq.pop();
        minn = min(minx[find_s(now.fr)], minx[find_s(now.to)]),
            maxn = max(maxx[find_s(now.fr)], maxx[find_s(now.to)]);
        minn = min(minn, now.val), maxn = max(maxn, now.val);
        merge_s(now.fr, now.to);
        minx[find_s(now.fr)] = minn, maxx[find_s(now.fr)] = maxn;
        if (find_s(1) == find_s(n)) 
        {
            ans = min(ans, minx[find_s(1)] + maxx[find_s(n)]);
        }
    }
    cout << ans << '\n';

}


signed main() {
    IOS;
    /**/int t;
    cin >> t;
    if(t>0)
    while (t--)
        solve();
    else {
        for (itn ik = 1; ik < t; ik++) {
            cin >> n >> m;
            for (itn i = 1; i <= m; i++) {
                int a, b, x; cin >> a >> b >> x;
                pq.push(edge(a, b, x));
            }

            if (ik == 12) {
                cout << n << ' ' << m << '\n';
                while (!pq.empty()) {
                    edge now = pq.top(); pq.pop();
                    cout << now.fr << ' ' << now.to << ' ' << now.val << '\n';
                }
            }
            while (!pq.empty())pq.pop();
        }
    }
    return 0;
}
posted @ 2025-07-31 18:00  WHUStar  阅读(3)  评论(0)    收藏  举报