网上看了题解才知道的,和HDU4711 杭州赛类似
先BFS找到两两间的最短距离;
在DFS枚举所有路径找到最优解。。。。
#include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #include<iostream> #include <queue> #include <stack> #include<algorithm> #include<set> using namespace std; #define inf 2147483647 #define eps 1e-8 #define LL long long #define M 50005 #define mol 1000000007 struct node { int x,y; }; int dir[4][2]={0,1,0,-1,1,0,-1,0}; int w,n,l,m,a[55]; char s[55][55]; int vis[55][55],f[55][55],step[55][55],viss[55]; int sum,ans; int pd(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m&&s[x][y]!='*') return 1; return 0; } void bfs(int x,int y,int e) { queue<node>Q; node p,q; int dx,dy; p.x=x;p.y=y; vis[x][y]=1; step[x][y]=0; Q.push(p); while(!Q.empty()) { q=Q.front (); Q.pop(); for(int i=0;i<4;i++) { dx=q.x+dir[i][0]; dy=q.y+dir[i][1]; if(pd(dx,dy)&&!vis[dx][dy]) { p.x=dx;p.y=dy; vis[dx][dy]=1; step[dx][dy]=step[q.x][q.y]+1; if(s[dx][dy]=='<') f[e][w+1]=step[dx][dy]; else if(s[dx][dy]=='@') f[e][0]=step[dx][dy]; else if(s[dx][dy]>='A'&&s[dx][dy]<='Z') f[e][s[dx][dy]-'A'+1]=step[dx][dy]; Q.push(p); } } } } void dfs(int x,int y,int t) { if(t>l||ans==sum) return; if(x==w+1&&y>ans) ans=y; for(int i=1;i<=w+1;i++) { if(!viss[i]&&f[x][i]) { viss[i]=1; dfs(i,y+a[i],t+f[x][i]); viss[i]=0; } } } int main() { int t,Case=1; scanf("%d",&t); while(t--) { sum=0;ans=-1; scanf("%d%d%d%d",&m,&n,&l,&w); int i,j; for(i=1;i<=w;i++) { scanf("%d",&a[i]); sum+=a[i]; } a[w+1]=0; for(i=0;i<n;i++) { scanf("%s",s[i]); } memset(vis,0,sizeof(vis)); memset(viss,0,sizeof(viss)); memset(f,0,sizeof(f)); for(i=0;i<n;i++) { for(j=0;j<m;j++) { memset(vis,0,sizeof(vis)); memset(step,0,sizeof(step)); if(s[i][j]=='@') { bfs(i,j,0); } else if(s[i][j]=='<') { bfs(i,j,w+1); } else if(s[i][j]>='A'&&s[i][j]<='Z') bfs(i,j,s[i][j]-64); } } viss[0]=1; dfs(0,0,0); printf("Case %d:\n",Case++); if(ans>=0) printf("The best score is %d.\n",ans); else printf("Impossible\n"); if(t) printf("\n"); } return 0; }