UVALive - 6455 Stealing Harry Potter's Precious (bfs+dfs)
https://cn.vjudge.net/problem/UVALive-6455
题目大意:题目上给出一个地图,其中@是人在地图上的出发点,#是墙,‘ . '是路。然后给出几个点,这些点表示财宝的所在地。问人是否能够得到所有的宝藏,如果能够的话给出所有的宝藏的最短的路径。
解题思路:由于只有最多4个宝藏所在地,所以只要用bfs找出出发点和财宝所在地距离到达其他点的步数。因为最多只有4个宝藏,所以可以暴力找出出发点到所有宝藏的最短距离。
暴力代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include <bits/stdc++.h> 5 using namespace std; 6 int n,m,k; 7 char s[110][110]; 8 int xx[4]= {1,-1,0,0},yy[4]= {0,0,1,-1}; 9 struct node 10 { 11 int x,y; 12 int dis[10]; 13 } pos[10]; 14 int bfs(node tmp,int id) 15 { 16 queue<pair<int,pair<int,int> > >que; 17 while(!que.empty()) 18 que.pop(); 19 int vis[110][110]; 20 memset(vis,0,sizeof(vis)); 21 que.push(make_pair(0,make_pair(tmp.x,tmp.y))); 22 vis[tmp.x][tmp.y]=1; 23 while(!que.empty()) 24 { 25 int tx=que.front().second.first,ty=que.front().second.second,len=que.front().first; 26 //printf("%d %d\n",tx,ty); 27 que.pop(); 28 for(int i=0; i<4; i++) 29 { 30 int lx=tx+xx[i],ly=ty+yy[i]; 31 if(0<=lx&&lx<n&&0<=ly&&ly<m) 32 { 33 if(vis[lx][ly]==0&&s[lx][ly]!='#') 34 { 35 vis[lx][ly]=1; 36 que.push(make_pair(len+1,make_pair(lx,ly))); 37 for(int j=0; j<=k; j++) 38 { 39 if(j!=id&&lx==pos[j].x&&ly==pos[j].y) 40 pos[id].dis[j]=len+1; 41 } 42 } 43 } 44 } 45 } 46 return 0; 47 } 48 int main() 49 { 50 while(~scanf("%d%d",&n,&m)) 51 { 52 if(n==0&&m==0) 53 break; 54 for(int i=0; i<n; i++) 55 { 56 scanf("%s",s[i]); 57 for(int j=0; j<m; j++) 58 if(s[i][j]=='@') 59 { 60 pos[0].x=i; 61 pos[0].y=j; 62 } 63 } 64 scanf("%d",&k); 65 for(int i=1; i<=k; i++) 66 { 67 scanf("%d%d",&pos[i].x,&pos[i].y); 68 pos[i].x--; 69 pos[i].y--; 70 } 71 for(int i=0; i<10; i++) 72 for(int j=0; j<10; j++) 73 pos[i].dis[j]=-1; 74 for(int i=0; i<=k; i++) 75 bfs(pos[i],i); 76 // for(int i=1; i<=k; i++) 77 // if(pos[0].dis[i]==-1) 78 // { 79 // printf("-1\n"); 80 // break; 81 // } 82 if(k==1) 83 { 84 printf("%d\n",pos[0].dis[1]); 85 } 86 else if(k==2) 87 { 88 int minn=10000000; 89 for(int i=1; i<=k; i++) 90 { 91 for(int j=1; j<=k; j++) 92 { 93 if(i==j) 94 continue; 95 minn=min(minn,pos[0].dis[i]+pos[i].dis[j]); 96 } 97 } 98 printf("%d\n",minn); 99 } 100 else if(k==3) 101 { 102 int minn=10000000; 103 for(int i=1; i<=k; i++) 104 { 105 for(int j=1; j<=k; j++) 106 { 107 for(int u=1; u<=k; u++) 108 { 109 if(i==j||j==u||i==u) 110 continue; 111 minn=min(minn,pos[0].dis[i]+pos[i].dis[j]+pos[j].dis[u]); 112 } 113 } 114 } 115 printf("%d\n",minn); 116 } 117 else if(k==4) 118 { 119 int minn=10000000; 120 for(int i=1; i<=k; i++) 121 { 122 for(int j=1; j<=k; j++) 123 { 124 for(int u=1; u<=k; u++) 125 { 126 for(int v=1; v<=k; v++) 127 { 128 if(i==j||i==u||i==v||j==u||j==v||u==v) 129 continue; 130 minn=min(minn,pos[0].dis[i]+pos[i].dis[j]+pos[j].dis[u]+pos[u].dis[v]); 131 } 132 } 133 } 134 } 135 printf("%d\n",minn); 136 } 137 138 } 139 return 0; 140 }
只是因为这个题目中的 k 是比较小的,如果 k 更大的话就不能暴力了。当 k 更大时可以用的 dfs 找到最短距离
dfs代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include <bits/stdc++.h> 5 using namespace std; 6 int n,m,k; 7 char s[110][110]; 8 int xx[4]= {1,-1,0,0},yy[4]= {0,0,1,-1}; 9 struct node 10 { 11 int x,y; 12 int dis[10]; 13 } pos[10]; 14 int bfs(node tmp,int id) 15 { 16 queue<pair<int,pair<int,int> > >que; 17 while(!que.empty()) 18 que.pop(); 19 int vis[110][110]; 20 memset(vis,0,sizeof(vis)); 21 que.push(make_pair(0,make_pair(tmp.x,tmp.y))); 22 vis[tmp.x][tmp.y]=1; 23 while(!que.empty()) 24 { 25 int tx=que.front().second.first,ty=que.front().second.second,len=que.front().first; 26 //printf("%d %d\n",tx,ty); 27 que.pop(); 28 for(int i=0; i<4; i++) 29 { 30 int lx=tx+xx[i],ly=ty+yy[i]; 31 if(0<=lx&&lx<n&&0<=ly&&ly<m) 32 { 33 if(vis[lx][ly]==0&&s[lx][ly]!='#') 34 { 35 vis[lx][ly]=1; 36 que.push(make_pair(len+1,make_pair(lx,ly))); 37 for(int j=0; j<=k; j++) 38 { 39 if(j!=id&&lx==pos[j].x&&ly==pos[j].y) 40 pos[id].dis[j]=len+1; 41 } 42 } 43 } 44 } 45 } 46 return 0; 47 } 48 int minn,vis[10]; 49 int dfs(int k,int tmp,int ans,int id) 50 { 51 if(tmp==k) 52 { 53 minn=min(minn,ans); 54 } 55 for(int i=1;i<=k;i++) 56 { 57 if(vis[i]==0) 58 { 59 vis[i]=1; 60 dfs(k,tmp+1,ans+pos[id].dis[i],i); 61 vis[i]=0; 62 } 63 } 64 return 0; 65 } 66 int main() 67 { 68 while(~scanf("%d%d",&n,&m)) 69 { 70 if(n==0&&m==0) 71 break; 72 for(int i=0; i<n; i++) 73 { 74 scanf("%s",s[i]); 75 for(int j=0; j<m; j++) 76 if(s[i][j]=='@') 77 { 78 pos[0].x=i; 79 pos[0].y=j; 80 } 81 } 82 scanf("%d",&k); 83 for(int i=1; i<=k; i++) 84 { 85 scanf("%d%d",&pos[i].x,&pos[i].y); 86 pos[i].x--; 87 pos[i].y--; 88 } 89 for(int i=0; i<10; i++) 90 for(int j=0; j<10; j++) 91 pos[i].dis[j]=-1; 92 for(int i=0; i<=k; i++) 93 bfs(pos[i],i); 94 // for(int i=1; i<=k; i++) 95 // if(pos[0].dis[i]==-1) 96 // { 97 // printf("-1\n"); 98 // break; 99 // } 100 memset(vis,0,sizeof(vis)); 101 minn=100000; 102 dfs(k,0,0,0); 103 if(minn==100000) 104 printf("-1\n"); 105 else 106 printf("%d\n",minn); 107 108 } 109 return 0; 110 }