[USACO16FEB]围栏Fenced In Platinum

题目:洛谷P3141。

题目大意:有一个方形区域,被分成若干区域。现在要去掉若干条围栏,使得所有区域连通,求最少去掉多少长度的围栏。

解题思路:贪心。建议画图思考。

先对围栏位置进行排序,然后相邻两条求差,再对差排序。

可以知道,每次取的是最短的一条围栏,结果一定是最优的(横向和竖向也要最短的优先),所以直接整行整列删即可。

但是全删了就会造成浪费,如果两个块已经连通,则不需要建边,所以乘的时候要注意。

然后求出答案即可。具体见代码。

注意64位整数。

C++ Code:

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
using namespace std;
int A,B,n,m,a[25050],b[25050],x[25050],y[25050];
inline int readint(){
	char c=getchar();
	for(;!isdigit(c);c=getchar());
	int d=0;
	for(;isdigit(c);c=getchar())
	d=(d<<3)+(d<<1)+(c^'0');
	return d;
}
int main(...){
	A=readint();B=readint();n=readint();m=readint();
	for(int i=1;i<=n;++i)
	a[i]=readint();
	for(int i=1;i<=m;++i)
	b[i]=readint();
	sort(a+1,a+n+1);
	sort(b+1,b+m+1);
	a[0]=b[0]=0;
	memset(x,0x3f,sizeof x);
	memset(y,0x3f,sizeof y);
	for(int i=1;i<=n;++i)
	x[i]=a[i]-a[i-1];
	x[n+1]=A-a[n];
	for(int i=1;i<=m;++i)
	y[i]=b[i]-b[i-1];
	y[m+1]=B-b[m];
	sort(x+1,x+n+2);
	sort(y+1,y+m+2);
	long long ans=(long long)x[1]*m+(long long)y[1]*n;
	int i=2,j=2;
	for(;i<=n+1&&j<=m+1;)
	if(x[i]<y[j])ans+=(long long)x[i++]*(m-j+2);
	else ans+=(long long)y[j++]*(n-i+2);
	printf("%lld
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Mrsrz/p/7725630.html