[BZOJ 1698] 荷叶池塘

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=1698

[算法]

        最短路

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 35
const int dx[8] = {1,-1,1,-1,2,-2,2,-2};
const int dy[8] = {2,2,-2,-2,1,1,-1,-1};

struct edge
{
    int to,nxt;
} e[MAXN * MAXN * MAXN * MAXN];

int n,m,sx,sy,tx,ty,tot;
int head[MAXN * MAXN];
int mp[MAXN][MAXN],dist[MAXN * MAXN];
long long cnt[MAXN * MAXN];
bool visited[MAXN][MAXN];

inline bool valid(int x,int y)
{
    return x >= 1 && x <= n && y >= 1 && y <= m;
}
inline int id(int x,int y)
{
    return (x - 1) * m + y;
}
inline void addedge(int u,int v)
{
    tot++;
    e[tot] = (edge){v,head[u]};
    head[u] = tot;
}
inline void dfs(int nowx,int nowy,int x,int y)
{
    for (int i = 0; i < 8; i++)
    {
        int nx = nowx + dx[i] , ny = nowy + dy[i];
        if (valid(nx,ny) && !visited[nx][ny] && mp[nx][ny] != 2)
        {
            visited[nx][ny] = true;
            if (!mp[nx][ny] || mp[nx][ny] == 4) addedge(id(x,y),id(nx,ny));
            else dfs(nx,ny,x,y);
        }
    }
}
inline void spfa(int x,int y)
{
    queue< int > q;
    static bool inq[MAXN * MAXN];
    memset(inq,false,sizeof(inq));
    memset(dist,0x3f,sizeof(dist));
    dist[id(x,y)] = 0;
    cnt[id(x,y)] = 1;
    q.push(id(x,y));
    while (!q.empty())
    {
        int cur = q.front();
        q.pop();
        if (cur == id(tx,ty)) continue;
        inq[cur] = false;
        for (int i = head[cur]; i; i = e[i].nxt)
        {
            int v = e[i].to;
            if (dist[cur] + 1 < dist[v])
            {
                dist[v] = dist[cur] + 1;
                cnt[v] = cnt[cur];
                if (!inq[v])
                {
                    inq[v] = true;
                    q.push(v);
                }
            } else if (dist[cur] + 1 == dist[v]) cnt[v] += cnt[cur];
        }
        cnt[cur] = 0;
    }
}

int main()
{
    
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            scanf("%d",&mp[i][j]);
            if (mp[i][j] == 3)
            {
                sx = i;
                sy = j;    
            }    
            if (mp[i][j] == 4)
            {
                tx = i;
                ty = j;
            }
        }    
    }    
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            memset(visited,false,sizeof(visited));
            visited[i][j] = true;
            if (mp[i][j] != 2)
                dfs(i,j,i,j);
        }
    }
    spfa(sx,sy);
    if (dist[id(tx,ty)] > 1e8) 
    {
        printf("-1\n");
        return 0;
    }
    printf("%d\n%lld\n",dist[id(tx,ty)] - 1,cnt[id(tx,ty)]);
    
    return 0;
}

 

posted @ 2018-08-20 16:52  evenbao  阅读(243)  评论(0编辑  收藏  举报