貌似和前段时间的一场网络赛一个类型,状态压缩判断走没走过,然后裸bfs到终点。
其实这类题目很简单就是一个bfs模板,无非就是有一些坑,比如这一题。。一个格子可以有多把钥匙汗==


1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 struct dian{ 7 int x,y,state,time; 8 }; 9 int n,m; 10 int xx[]={1,-1,0,0}; 11 int yy[]={0,0,1,-1}; 12 int vis[55][55][1100]; 13 int g[55][55][55][55],num[55][55],key[55][55][55]; 14 int bfs() 15 { 16 queue<dian>q; 17 dian n1,n2; 18 int i,j,temp,x; 19 while (!q.empty()) q.pop(); 20 n1.x=1; n1.y=1; n1.time=0; x=0; 21 for (i=1;i<=num[1][1];i++) x=(x|(1<<key[1][1][i])); 22 n1.state=x; q.push(n1); vis[1][1][n1.state]=1; 23 while (!q.empty()) 24 { 25 n1=q.front(); q.pop(); 26 // printf("%d %d %d %d\n",n1.x,n1.y,n1.state,n1.time); 27 if (n1.x==n&&n1.y==m) return n1.time; 28 for (i=0;i<4;i++) 29 { 30 n2.x=n1.x+xx[i]; n2.y=n1.y+yy[i]; 31 if (n2.x<=0||n2.x>n||n2.y<=0||n2.y>m) continue; 32 if (g[n1.x][n1.y][n2.x][n2.y]!=-1){ 33 temp=(1<<g[n1.x][n1.y][n2.x][n2.y]); 34 if ((n1.state&temp)==0) continue; 35 } 36 x=n1.state; 37 for (j=1;j<=num[n2.x][n2.y];j++){ 38 temp=(1<<key[n2.x][n2.y][j]); 39 x=(x|temp); 40 } 41 n2.state=x; 42 if (vis[n2.x][n2.y][n2.state]) continue; 43 vis[n2.x][n2.y][n2.state]=1; 44 n2.time=n1.time+1; 45 q.push(n2); 46 } 47 } 48 return -1; 49 } 50 int main() 51 { 52 int p,k,i,kind,x1,x2,y1,y2,s; 53 while (~scanf("%d%d%d",&n,&m,&p)) 54 { 55 memset(g,-1,sizeof(g)); 56 memset(num,0,sizeof(num)); 57 memset(vis,0,sizeof(vis)); 58 scanf("%d",&k); 59 for (i=1;i<=k;i++) 60 { 61 scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&kind); 62 g[x1][y1][x2][y2]=kind; 63 g[x2][y2][x1][y1]=kind; 64 } 65 scanf("%d",&s); 66 for (i=1;i<=s;i++) 67 { 68 scanf("%d%d%d",&x1,&y1,&kind); 69 num[x1][y1]++; 70 key[x1][y1][num[x1][y1]]=kind; 71 } 72 printf("%d\n",bfs()); 73 } 74 return 0; 75 }