[USACO07FEB]荷叶塘Lilypad Pond
题目
链接[https://www.luogu.org/problemnew/show/P1606]
解法
因为我们要求释放荷叶的最小个数,可以联想到最短路。
然后我们考虑从当前节点出发能到哪些点,然后向周围点连一条长度为1的边就可以了。
然后方案数就是最短路计数。
但是从当前点出发可能连到一个已经有的荷叶,是不需要花费的,我们就以这个荷叶为跳板,
看他能免费到哪些节点,dfs建一下边就可以了。
代码
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <cctype> #include <vector> #include <queue> #define INF 2139062143 #define MAX 0x7ffffffffffffff #define del(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; template<typename T> inline void read(T&x) { x=0;T k=1;char c=getchar(); while(!isdigit(c)){if(c=='-')k=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k; } const int maxn=30*30+15; vector<int> G[maxn]; void add_edge(int u,int v) { G[u].push_back(v); } int n,m,s,t; int get_id(int i,int j) { return (i-1)*m+j; } bool vis[maxn]; int a[35][35]; int dx[]={1,1,-1,-1,2,2,-2,-2}; int dy[]={2,-2,2,-2,-1,1,-1,1}; void build(int cur,int x,int y) { if(vis[get_id(x,y)]) return; vis[get_id(x,y)]=1; for(int i=0;i<8;i++) { int xx=x+dx[i],yy=y+dy[i]; if(xx<1||yy<1||xx>n||yy>m||vis[get_id(xx,yy)]) continue; if(a[xx][yy]==2) continue; if(a[xx][yy]==1) build(cur,xx,yy); else { add_edge(cur,get_id(xx,yy)); vis[get_id(xx,yy)]=1; } } } int dis[maxn]; ll num[maxn]; void spfa() { del(vis,0); for(int i=1;i<=n*m;i++) dis[i]=INF; queue<int> q; dis[s]=0;vis[s]=1;q.push(s);num[s]=1ll; while(!q.empty()) { int u=q.front();q.pop();vis[u]=0; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(dis[v]>dis[u]+1) { num[v]=num[u]; dis[v]=dis[u]+1; if(!vis[v]) { vis[v]=1; q.push(v); } } else if(dis[v]==dis[u]+1) num[v]+=num[u]; } } } int main() { read(n),read(m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { read(a[i][j]); if(a[i][j]==3) s=get_id(i,j); if(a[i][j]==4) t=get_id(i,j); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(a[i][j]==1||a[i][j]==2) continue; del(vis,0);build(get_id(i,j),i,j); } spfa(); if(dis[t]==INF) printf("-1\n"); else printf("%d\n%lld\n",dis[t]-1,num[t]); return 0; }

浙公网安备 33010602011771号