2013杭州现场赛B题
这道题的英文很通俗易懂,连我都能看懂~~~
题意:给出n*m的矩阵,还有给出几个点,要你在矩阵中遍历这几个点(不重复)
遍历的最短距离。。
刚看起来好像是tsp问题额,这么难???
不过看了一下最多的点数就只有4+起点,唉,直接暴搜。。
这题主要就是求出每两点的最短距离(BFS)。
然后就是枚举全部路径(DFS)
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
char map[105][105];
int vivsit[105][105];
int dir[][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int N,M;
int si,sj,k,ans;
int p[10][10];
struct node
{
int x,y;
}node[10];
struct qu
{
int x,y;
int min;
};
int BFS(int i,int j)
{
memset(vivsit,0,sizeof(vivsit));
queue<qu> q;
struct qu var,var1;
var.x = node[i].x;
var.y = node[i].y;
var.min = 0;
q.push(var);
vivsit[var.x][var.y] = 1;
while(!q.empty())
{
var = q.front();
q.pop();
if(var.x==node[j].x && var.y==node[j].y)
return var.min;
for(int k=0;k<4;k++)
{
int xx = var.x+dir[k][0];
int yy = var.y+dir[k][1];
if(map[xx][yy]!='#' && vivsit[xx][yy]==0)
{
vivsit[xx][yy] = 1;
var1.x = xx;
var1.y = yy;
var1.min = var.min+1;
q.push(var1);
}
}
}
return -1;
}
void DFS(int f[],int k,int pre,int sum,int mm)
{
if(mm==k)
{
if(ans>sum)
ans = sum;
}
for(int i=1;i<=k;i++)
if(f[i]==0)
{
f[i] = 1;
DFS(f,k,i,sum+p[pre][i],mm+1);
f[i] = 0;
}
}
int main()
{
int i,j;
while(scanf("%d%d",&N,&M) && N+M!=0)
{
memset(map,'#',sizeof(map));
for( i=1;i<=N;i++)
{
getchar();
for( j=1;j<=M;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='@')
{
si = i;
sj = j;
}
}
}
scanf("%d",&k);
node[0].x = si;
node[0].y = sj;
for( i=1;i<=k;i++)
scanf("%d%d",&node[i].x,&node[i].y);
memset(p,-1,sizeof(p));
int flag = 0;
for( i=0;i<=k;i++)
{
p[i][i] = 0;
for( j=0;j<=k;j++)
{
if(p[i][j]==-1 && flag==0)
{
p[j][i] = p[i][j] = BFS(i,j);
if(p[i][j]==-1)
{
flag = 1;
break;
}
}
}
}
if(flag==1)
{
printf("-1\n");
continue;
}
int f[10];
ans = 100009;
memset(f,0,sizeof(f));
DFS(f,k,0,0,0);
printf("%d\n",ans);
}
return 0;
}