Solution - P5687 [CSP-S2019 江西] 网格图
一道简单题,可惜我最开始没做出来,经过一位神犇的指导才 AC。
思路
首先考虑 Kruskal。但是复杂度 \(O(n^2 \log n^2)\),别想了。
但是注意到有很多边(同一行/列)的权值是一样的,于是直接把行/列排序,然后贪心。但是注意判一下环,不然就不是生成树了。
判环很简单,令已经加入了 \(cnt_1\) 行、\(cnt_2\) 列,往答案里加边时减去 \(cnt_i-1\) 条边(减去一是因为需要和树相连)就可以了。复杂度 \(O(n \log n)\)。
于是,没了。
代码
#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 300005
using namespace std;
llong a[N], b[N];
llong n, m, ans;
llong cnt1 = 1, cnt2 = 1;
int main(){
scanf("%lld %lld", &n, &m);
for(rint i = 1, x; i <= n; ++i) scanf("%lld", &a[i]);
for(rint i = 1, x; i <= m; ++i) scanf("%lld", &b[i]);
sort(a+1, a+n+1), sort(b+1, b+m+1);
ans = a[1]*(m-1)+b[1]*(n-1);
rint i = 2, j = 2;
while(i <= n && j <= m){
if(a[i] <= b[j]) ans += 1ll*a[i]*(m-cnt2), ++cnt1, ++i;
else ans += 1ll*b[j]*(n-cnt1), ++cnt2, ++j;
}
printf("%lld", ans);
return 0;
}
/*
3 3
2 4 3
1 3 2
*/

浙公网安备 33010602011771号