P1606 [USACO07FEB] Lilypad Pond G

/*
½«Ë®£¨0£©ÓëÖÜΧµÄË®»òÕß Á«»¨£¨1£©ËÄÖܵÄË®Á¬±ß   ¾­¹ýµÄ±ß¾ÍÊÇ×îСÊý
::²»¿ÉÒÔ½«Ë®ºÍÁ«»¨ Á¬±ß ÒòΪÁ«»¨²»ÐèÒªÔÙ·ÅÖà 
spfa ×îС·¾¶¼ÆÊý 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
//#include<queue>
//#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e2+10 ;

int dx[8]={2,2,-2,-2,1,-1,1,-1},dy[8]={-1,1,-1,1,2,2,-2,-2};

int n,m,mp[maxn][maxn],biao[maxn][maxn],st,ed,b[maxn][maxn];
int head[maxn*maxn],to[maxn*maxn<<3],nxt[maxn*maxn<<3],tot;
int dis[maxn*maxn],vis[maxn*maxn];
ll cnt[maxn*maxn];

void add(int u,int v){
    to[++tot]=v,nxt[tot]=head[u],head[u]=tot;
}

void dfs(int op,int x,int y)
{
    b[x][y]=1;
    for(int i=0;i<8;i++)
    {
        int xx=x+dx[i],yy=y+dy[i];//
        if(xx<1||xx>n||yy<1||yy>m||b[xx][yy]) continue;
        if(mp[xx][yy]==1) b[xx][yy]=1,dfs(op,xx,yy);
        if(mp[xx][yy]!=2) b[xx][yy]=1,add(op,biao[xx][yy]);
    }
}

void spfa()
{
    memset(dis,0x3f3f3f3f,sizeof(dis));
    cnt[st]=1;
    
    queue<int> q; q.push(st);dis[st]=0;vis[st]=1;
    
    while(!q.empty())
    {
        int u=q.front();q.pop(); vis[u]=0;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]>dis[u]+1)
            {
                dis[v]=dis[u]+1;
                cnt[v]=cnt[u];
                if(vis[v]==0) q.push(v),vis[v]=1;
            }
            else if(dis[v]==dis[u]+1) cnt[v]+=cnt[u];
        }
    }
}

int main(){
    scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            biao[i][j]=(i-1)*m+j;
    for(int i=1;i<=n;i++){ 
        for(int j=1;j<=m;j++){
            scanf("%d",&mp[i][j]);
            if(mp[i][j]==3) st=biao[i][j];
            if(mp[i][j]==4) ed=biao[i][j];
        }
    }
    
    for(int i=1;i<=n;i++)
        for( int j=1;j<=m;j++){
        if(mp[i][j]==0||mp[i][j]==3){
            memset(b,0,sizeof(b));
            dfs(biao[i][j],i,j);
        }
    }

    spfa();
    
    if(dis[ed]>=0x3f3f3f3f) cout<<-1<<'\n';
    else if(dis[ed]<0x3f3f3f3f) cout<<dis[ed]-1<<'\n'<<cnt[ed]<<'\n';
    
    return 0;
}

 

posted @ 2023-09-17 16:04  JMXZ  阅读(12)  评论(0)    收藏  举报