最小生成树,找规律
本题要点:
1、n <= 3 * 10^5, 求最小生成树,kruskal 和 prim 都严重超时。 这题图的边密密麻麻,分布有规律。
2、首先, n * m 个点, 最小生成树连上的边有 n * m - 1 条。每连上一条边,都选择的是当前可以选择的最小的边。
3、数组 a[MaxN], b[MaxN] 先从小到大排序。然后, 依次从两个数组中,选择最小的数。
如果这两个数组的头元素相等,就要看 n 和 m 的大小来选择了。 n < m, 两个数组的头元素相等,选择行,也就是数组a 首元素。
打比方,从数组中a,选择 a[k], 相当于在第 k 行,添加边长是 a[k] 的边。 具体添加多少个 a[k], 就看此时,已经
处理了多少列(也就是从数组 b 中选择了多少个数)。假如处理了 tmp 列,此时,在第k行,加入 (m - tmp) 条边长是
a[k] 的 边。 不过需要注意的是:如果当前已经处理的行数 row 和已经处理的列数 col满足
if(row == 0 || col == 0), 第 k 行,添加边长是 a[k] 的边 (m - 1) 条。
4、long long select = 0; // 增加了多少个边
long long ans = 0; // 最小生成树的总边长。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MaxN = 3e5 + 10;
long long n, m;
int a[MaxN], b[MaxN];
void solve()
{
int row = 0, col = 0; // 当前已经选择的行,列
long long ans = 0;
long long select = 0; // 增加了多少个边
sort(a