题解 P2919 [USACO08NOV]守护农场Guarding the Farm

Posted hiraeth-dh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P2919 [USACO08NOV]守护农场Guarding the Farm相关的知识,希望对你有一定的参考价值。

rt

若地图中一个元素所邻接的所有元素都比这个元素高度要小(或它邻接的是地图的边界),则该元素和其周围所有按照这样顺序排列的元素的集合称为一个小山丘。

那么我们可以用一个结构体类型记录所有非零高度的横纵坐标以及相应的高度值

然后对高度进行排序 对每一次高度进行$dfs$ 及时删除所有的联通高度的小山丘

很显然 如果从一个给定高度的山丘的最高高度进行$dfs$ 一定可以将该山丘的所有高度清零

犯了一个很zz的错误

在递归调用的时候 $tmp$定义的全局变量 然后在递归调用的时候 在下一次递归结束

之后 tmp的值已经被改变了 而当前层的tmp还未判断完成

我发誓我以后在$dfs$里面只用局部变量 手动再见

代码如下:

#include<bits/stdc++.h>
using namespace std;
int a[705][705],ans,px,py,tot,m,n;
int dx[]={0,0,1,1,1,-1,-1,-1};
int dy[]={1,-1,0,1,-1,0,1,-1};
struct p{
    int x,y,num;
}f[490005];
void dfs(int x,int y){
    int tmp=a[x][y];//在删除之前保存数据 
    //!!!每次循环都要调用tmp 在下一次递归结束之后 tmp的值已经被改变了 而当前层的tmp还未判断完成 
    a[x][y]=0;
    for (int i=0;i<=7;i++){
        px=x+dx[i];py=y+dy[i];
        if (px>0&&px<=n&&py>0&&py<=m&&tmp>=a[px][py]&&a[px][py]!=0) dfs(px,py);
    }
}
bool cmp(p a,p b){
    return a.num>b.num; 
}
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
            if (a[i][j]) {
                tot++;
                f[tot].x=i;
                f[tot].y=j;
                f[tot].num=a[i][j];
            } 
        }
    sort(f+1,f+tot+1,cmp);
    for (int i=1;i<=tot;i++)
        if (a[f[i].x][f[i].y]) {//如果在删除过程当中没有被删除 
            ans++;
            dfs(f[i].x,f[i].y);
        } 
    printf("%d\n",ans);
    return 0;
}

以上是关于题解 P2919 [USACO08NOV]守护农场Guarding the Farm的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1619 / P2919 [USACO08NOV]守护农场Guarding the Farm

题解Luogu2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

题解 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

最短路bzoj1726: [Usaco2006 Nov]Roadblocks第二短路

题解 P2920 [USACO08NOV]时间管理Time Management

题解P2916 [USACO08NOV]安慰奶牛Cheering up the Cow-C++