poj 3271 Lilypad Pond bfs

来源:互联网 发布:知柏地黄丸吃多少粒 编辑:程序博客网 时间:2024/06/05 19:28

因为有了1的存在,使得问题变得比较难搞了,所以比较简单的做法就是把1去掉,先做一次bfs,处理出每个点能够一步到达的点(一定是1步).

然后就可以在新图上用bfs算出两个点之间的最短路,和最短路的个数。(至于原题问的为什么是这个,很简单,因为建造的香蒲要最少,所以不会重复建造,不会多建造,所以就是求最短路,至于路径数,因为现在路径长度是简单递增的,所以直接累加就可以了)。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn=30+9;int dist[maxn][maxn],a[maxn][maxn];int n,m;bool d[maxn][maxn][maxn][maxn];int quex[maxn*maxn],quey[maxn*maxn];long long ans[maxn][maxn];bool text[maxn][maxn];void bfs2(int t,int s){    int front=1,end=0;    quex[++end]=t;    quey[end]=s;    memset(dist,50,sizeof(dist));    memset(ans,0,sizeof(ans));    dist[t][s]=0;    ans[t][s]=1;    while(front<=end)    {        int x=quex[front],y=quey[front++];        if(a[x][y]==2) continue;        for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        if(d[x][y][i][j])        {            if(dist[i][j]==dist[x][y]+1)            ans[i][j]+=ans[x][y];            else if(dist[i][j]>dist[x][y]+1)            {                dist[i][j]=dist[x][y]+1;                ans[i][j]=ans[x][y];                quex[++end]=i;                quey[end]=j;            }        }    }}void bfs(int t,int s){    memset(text,0,sizeof(text));    int front=1,end=0;    quex[++end]=t;    quey[end]=s;    text[t][s]=1;    while(front<=end)    {        int x=quex[front],y=quey[front++];        for(int i=-1;i<=1;i+=2)        for(int j=-1;j<=1;j+=2)        for(int k=1;k<=2;k++)        {            int tmp=1;            if(k==1) tmp=2;            int tox=x+i*k,toy=j*tmp+y;            if(tox>=1&&tox<=n&&toy>=1&&toy<=m)            if(!text[tox][toy])            {                text[tox][toy]=1;                if(a[tox][toy]==1)                {                    quex[++end]=tox;                    quey[end]=toy;                }                else                {                    d[t][s][tox][toy]=1;                }            }        }    }}int main(){    while(scanf("%d %d",&n,&m)!=EOF)    {        int t,s,tox,toy;        for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        {            scanf("%d",&a[i][j]);            if(a[i][j]==3)            {                t=i;                s=j;            }            else if(a[i][j]==4)            {                tox=i;                toy=j;            }        }        memset(d,0,sizeof(d));        for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        bfs(i,j);        bfs2(t,s);        if(dist[tox][toy]>1e3)        {            printf("-1\n");        }        else        {            printf("%d\n%lld\n",dist[tox][toy]-1,ans[tox][toy]);        }    }    return 0;}