题目链接:
P1606 [USACO07FEB]Lilypad Pond G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
解题思路:先将所有荷叶都铺上然后跑一遍最短路计数即可:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #define x first #define y second using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 35, M = N * N , E = M * N * N; int n, m; LL cnt[M]; bool vis[M]; int dist[M]; int idx[N][N]; bool st[N][N]; int map[N][N]; PII start, last; int h[M], e[E], ne[E], w[E], idxs; int dx[8] = {2, 2, -2, -2, 1, -1, 1, -1}; int dy[8] = {-1, 1, -1, 1, 2, 2, -2, -2}; void add(int a, int b) { e[idxs] = b; ne[idxs] = h[a]; h[a] = idxs; idxs ++ ; } void dfs(int sum, int x, int y)//仔细理解sum的含义,它可能跳到一个荷叶A上,然后又跳到一个水B上 { //此时要从sum所在的点向B连一条边 if (st[x][y]) return ; st[x][y] = true; for (int i = 0; i < 8; i ++ ) { int a = x + dx[i], b = y + dy[i]; if (a < 1 || a > n || b < 1 || b > m) continue; if (st[a][b]) continue; if (map[a][b] == 1) dfs(sum, a, b);//若它可以跳到另一个荷花上,则递归到下一个荷花 else if (map[a][b] != 2) { st[a][b] = true; add(sum, idx[a][b]); } } } void spfa(int S) { queue<int> q; q.push(S); for (int i = 1; i <= n * m; i ++ ) dist[i] = 0x3f3f3f3f; dist[S] = 0; cnt[S] = 1; while (q.size()) { int t = q.front(); q.pop(); vis[t] = false; for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] > dist[t] + 1) { cnt[j] = cnt[t]; dist[j] = dist[t] + 1; if (!vis[j]) { q.push(j); vis[j] = true; } } else if (dist[j] == dist[t] + 1) cnt[j] += cnt[t]; } } } int main() { cin >> n >> m; memset(h, -1, sizeof h); for (int i = 1, t = 0; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) { cin >> map[i][j]; idx[i][j] = ++ t; if (map[i][j] == 3) start = {i, j}; if (map[i][j] == 4) last = {i, j}; } for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) if (map[i][j] == 0 || map[i][j] == 3) { memset(st, false, sizeof st); dfs(idx[i][j], i, j); } spfa(idx[start.x][start.y]); if (dist[idx[last.x][last.y]] == 0x3f3f3f3f) puts("-1"); else { cout << dist[idx[last.x][last.y]] - 1<< endl;//最短路最终求的是边数,我们要求点数所以要减一 cout << cnt[idx[last.x][last.y]] << endl; } return 0; }