poj 2375 Cow Ski Area bfs

这个题目用tarjan找联通块,缩点,然后统计出入度为0的点理论上是可行的,但问题是会暴栈。考虑到这个题目的特殊性,可以直接用一次bfs找到数字相同且联通的块,这就是一个联通块,然后缩点,统计出入度即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=1e3+9;
int a[maxn][maxn];
int con;
int ss[maxn*maxn],in[maxn*maxn],out[maxn*maxn];
int n,m;
struct
{
    int t,s;
}que[maxn*maxn];
bool text[maxn*maxn];
void bfs()
{
    con=0;
    memset(text,0,sizeof(text));
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(!text[i*m+j])
    {
        int front=1,end=0;
        que[++end].t=i;
        que[end].s=j;
        text[i*m+j]=1;
        while(front<=end)
        {
            int t=que[front].t,s=que[front++].s;
            for(int p=-1;p<=1;p++)
            for(int q=-1;q<=1;q++)
            if(fabs(p)+fabs(q)==1&&t+p>=1&&t+p<=n&&s+q>=1&&s+q<=m)
            if(a[t][s]==a[t+p][s+q])
            if(!text[(t+p)*m+s+q])
            {
                text[(t+p)*m+s+q]=1;
                que[++end].t=t+p;
                que[end].s=s+q;
            }
        }
        con++;
        for(int i=1;i<=end;i++)
        {
            ss[que[i].t*m+que[i].s]=con;
        }
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d %d",&m,&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf("%d",&a[i][j]);
        bfs();
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        for(int p=-1;p<=1;p++)
        for(int q=-1;q<=1;q++)
        if(fabs(p)+fabs(q)==1&&i+p>=1&&i+p<=n&&j+q>=1&&j+q<=m)
        if(a[i][j]>=a[i+p][j+q])
        if(ss[(i+p)*m+j+q]!=ss[i*m+j])
        {
            in[ss[(i+p)*m+j+q]]++;
            out[ss[i*m+j]]++;
        }
        int ansin=0,ansout=0,ans;
        for(int i=1;i<=con;i++)
        {
            if(in[i]==0)
            ansin++;
            if(out[i]==0)
            ansout++;
        }
        ans=max(ansin,ansout);
        if(con<=1)
        printf("0
");
        else
        printf("%d
",ans);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3293822.html