【P2213 [USACO14MAR]The Lazy Cow S】
跟老师练过(唯手熟尔),题目大体是要求最小生成树的。因为最小生成树的计算方式不一样。所以可能拼接起来更好,先假设一部分已知,求另一部分。题目已知,有一颗不全的生成树,现在要往里添加点权值。多出来的部分就是所添加的两点的点权加上二倍的边权,意思是走两次。 大概就是这样的吧。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
int n,m,k,x,y,xl,yl,xr,yr;
int ans=-0x7fffffff,a[N][N],b[N*2][N*2];
int main () {
scanf("%d%d",&n,&k);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&a[i][j]);
m=n*2-1;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
b[i+j-1][n-i+j]=a[i][j];
for(int i=1; i<=m; i++)
for(int j=1; j<=m; j++)
b[i][j]+=b[i][j-1];
for(int i=1; i<=m; i++)
for(int j=1; j<=m; j++)
b[i][j]+=b[i-1][j];
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
x=i+j-1,y=n-i+j;
xl=x-k,yl=y-k,xr=x+k,yr=y+k;
if(xl<1)
xl=1;
if(yl<1)
yl=1;
if(xr>m)
xr=m;
if(yr>m)
yr=m;
ans=max(ans,b[xr][yr]-b[xr][yl-1]-b[xl-1][yr]+b[xl-1][yl-1]);
}
printf("%d\n",ans);
return 0;
}