您的位置:首页 > 其它

hdu 4771 Stealing Harry Potter's Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

2014-10-10 17:19 691 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771

题目意思:'@' 表示的是起点,'#' 表示的是障碍物不能通过,'.' 表示的是路能通过的;

目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离;

解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点 j 的距离;

然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的;

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<string>
#include<cmath>
using namespace std;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int m,n;
int sx,sy,T;
int ans[6][6];//点之间的距离
char Map[110][110];
int vis[110][110];//标记路径
struct node
{
int x,y,step;
}a[6],now,eed;
int bfs(int T1,int ee,int vv)
{
int TT=0;
vis[a[T1].x][a[T1].y]=vv;//每次标记的都发生了变化,这样vis数组不用每次都清零
queue< node >p;
now.x = a[T1].x;
now.y = a[T1].y;
now.step = 0;
p.push(now);
while(!p.empty())
{
now=p.front();
p.pop();
for(int i=T1+1; i<=T; i++)
{
if(now.x == a[i].x && now.y == a[i].y)
{
ans[T1][i]=ans[i][T1] = now.step;
TT++;
}
}
for(int i=0; i<4; i++)
{
eed.x = now.x + dir[i][0]; eed.y = now.y + dir[i][1];
if(eed.x>=1 && eed.x<=m && eed.y>=1 && eed.y<=n && vis[eed.x][eed.y]!=vv && Map[eed.x][eed.y]!='#')
{
eed.step = now.step+1;
vis[eed.x][eed.y] =  vv;
p.push(eed);
}
}
if(TT == ee) //如果该访问的点都访问了,直接返回;
return 1;
}
return -1 ;//如果其中有点不能访问到,直接返回-1,输出 -1 ;
}

int net[10],ans1;
void dfs(int x,int step,int sum)
{
if(step==T)
{
if(ans1>sum) ans1=sum;
return;
}
for(int i=0;i<=T;i++)
if(!net[i])
{
net[i]=1;
dfs(i,step+1,sum+ans[x][i]);
net[i]=0;
}
}
int main()
{
int x,y;
//  freopen("in1.txt","r",stdin);
//  freopen("out1.txt","w",stdout);
while(cin>>m>>n && m+n)
{
ans1=1000000;
memset(ans,0,sizeof(ans));
memset(net,0,sizeof(net));
memset(vis,0,sizeof(vis));
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
{
scanf(" %c",&Map[i][j]);
if(Map[i][j] == '@')
{
sx= i; sy = j;
}
}
scanf("%d",&T);
a[0].x=sx; a[0].y=sy;
for(int i=1; i<=T; i++)
{
scanf("%d %d",&x,&y);
a[i].x = x;
a[i].y = y;
}
int flag = 0 ;
for(int i = 0; i<T; i++)
{

flag = bfs(i,T-i,i+1);
if(flag == -1)
break;
}
if(flag == -1)
printf("-1\n");
else
{
net[0]=1;
dfs(0,0,0);
printf("%d\n",ans1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: