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

*/
posted @ 2025-04-18 19:59  Hootime  阅读(74)  评论(2)    收藏  举报