标签:init char div 分享 顶点 acm 模型 xxxxx 就是
Description
Input
Output
Sample Input
7 5 ....... .o...*. ....... .*...*. ....... 15 13 .......x....... ...o...x....*.. .......x....... .......x....... .......x....... ............... xxxxx.....xxxxx ............... .......x....... .......x....... .......x....... ..*....x....*.. .......x....... 10 10 .......... ..o....... .......... .......... .......... .....xxxxx .....x.... .....x.*.. .....x.... .....x.... 0 0
给出一个地图,’.’表示地板,可到达,’x’表示家具,不可到达,’o’表示机器人的位置,’*’表示脏地板,
要求机器人清理完所有的脏地板,并且所走距离最小,如无解,输出-1。机器人从一块地板只能沿着上下左右的某一
方向走到另一块地板,且距离为1。
题目模型:
将机器人的位置和各个脏地板的位置看成一个图的各个顶点,那么题目的本质就是要求在一个无向图
中,遍历各个顶点至少一次,使得总路径最小。
经过分析后,可以发现此题即是典型的TSP问题,也就是旅行商问题或汉密尔顿通路。此题要求的就是
旅行商问题的最优值。
思路: 比赛的时候碰到这题两个小时都在搞这道题,以为一个bfs暴力就过了结果自己测试出好多样例错误就不知道怎
么改了;看了题解才知道是dfs+bfs
典型的acm开拓思维的题型,第一次遇见;
先bfs求出任意两点之间的最短距离,然后dfs求出哈密顿图的最短距离即可,
将机器人和脏地板看成顶点,先求出顶点两两之间的最短距离,此时问题便转换成了求解汉密尔顿通路的最优值,
因此只要从起点出发再进行一次DFS即可求出最优解即可。AC代码求解最短路径是用BFS的,因为这相当于一个迷宫,
直接BFS即可求出各顶点的最短路径。
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; #define INF 0x7fffffff char map1[100][100]; int book[100][100]; int dis[100][100]; queue<struct node>Q; struct node { int x; int y; int s; } p[100],e,s; int use[22]; int ans,a; int bfs(int n,int m)///记录两两垃圾与机器人的最短距离 { int next[4][2]={{0,1},{1,0},{-1,0},{0,-1}}; memset(book,0,sizeof(book)); while(!Q.empty()) Q.pop(); int i; Q.push(s); while(!Q.empty()) { struct node l,g; g=Q.front(); Q.pop(); for(i=0;i<4;i++) { l=g; l.x+=next[i][0]; l.y+=next[i][1]; l.s++; if(l.x<0||l.y<0||l.x>=m||l.y>=n||book[l.x][l.y]==1||map1[l.x][l.y]==‘x‘) continue; book[l.x][l.y]=1; if(l.x==e.x&&l.y==e.y) return l.s; Q.push(l); } } return INF; } void dfs(int s,int num,int len)///搜索最短路径 { int i; if(num==0&&len<ans) { ans=len; return ; } if(len>ans) return ; for(i=0;i<a;i++) { if(!use[i]&&dis[s][i]!=INF) { use[i]=1; dfs(i,num-1,len+dis[s][i]); use[i ]=0; } } return ; } int main() { int n,m,i,fa,j,st; while(scanf("%d%d",&n,&m)!=EOF) { getchar(); if(n==0&&m==0) break; fa=a=0; memset(dis,0,sizeof(dis)); for(i=0;i<m;i++) { scanf("%s",map1[i]); for(j=0;j<n;j++) { if(map1[i][j]==‘o‘||map1[i][j]==‘*‘) { p[a].x=i; p[a].y=j; if(map1[i][j]==‘o‘) { st=a; } a++; } dis[i][j]=INF; } } for(i=0;i<a;i++) { for(j=i+1;j<a;j++) { s=p[i]; e=p[j]; s.s=0; dis[i][j]=dis[j][i]=bfs(n,m); if(dis[i][j]==INF) { fa=1; break; } } } if(fa) { printf("-1\n"); } else { ans=INF; memset(use,0,sizeof(use)); use[st]=1; dfs(st,a-1,0); printf("%d\n",ans); } } }
poj 2688 cleaning robot(bfs+dfs)
标签:init char div 分享 顶点 acm 模型 xxxxx 就是
原文地址:https://www.cnblogs.com/shuaihui520/p/8987483.html