【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;
}