题目:洛谷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; }