首页 > 代码库 > hdu 4771 求一点遍历所有给定点的最短路(bfs+dfs)

hdu 4771 求一点遍历所有给定点的最短路(bfs+dfs)

题目如题。题解如题。

由于目标点最多只有4个,先bfs出俩俩最短路(包括起点),再dfs最短路。)0s1A;(当年弱跪杭州之题,现看如此简单)

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct point
{
    int x,y;
    int cnt;
};
char a[105][105];
vector<point>po;
int n,m;int k;
int mindis[10][10];
int vis[105][105];
int f[4][2]={0,1,0,-1,1,0,-1,0};
int bfs(int s,int t)
{
      memset(vis,0,sizeof(vis));
      queue<point>q;
      po[s].cnt=0;
      po[t].cnt=-1;
      q.push(po[s]);
      vis[po[s].x][po[s].y]=1;
      while(!q.empty())
      {
          point cur=q.front();
          q.pop();
          point next;
          for(int i=0;i<4;i++)
           {
               next.x=cur.x+f[i][0];
               next.y=cur.y+f[i][1];
               if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&vis[next.x][next.y]==0&&a[next.x][next.y]!='#')
               {
                   next.cnt=cur.cnt+1;
                   if(next.x==po[t].x&&next.y==po[t].y)
                   {
                       return next.cnt;
                   }
                   q.push(next);
                   vis[next.x][next.y]=1;
               }
           }
      }
      return -1;
}
int mins=100000000;
int vis2[10];
void dfs(int u,int lev,int sumdis)
{
    if(sumdis>=mins)return ;
    if(lev==k)
    {
        if(sumdis<mins)
          {
              mins=sumdis;return ;
          }
    }
    for(int i=1;i<=k;i++)
    {
        if(!vis2[i])
        {
            vis2[i]=1;
            dfs(i,lev+1,sumdis+mindis[u][i]);
            vis2[i]=0;
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
       memset(mindis,0,sizeof(mindis));
       mins=100000000;
        po.clear();
        for(int i=0;i<n;i++)
        {
          getchar();
           for(int j=0;j<m;j++)
          {
             scanf("%c",&a[i][j]);
             if(a[i][j]=='@')
              {
                  point txy;txy.x=i;txy.y=j;
                  po.push_back(txy);
              }
          }
        }
        scanf("%d",&k); int aa,bb;
        for(int i=0;i<k;i++)
          {
              scanf("%d%d",&aa,&bb);
              point txy;txy.x=aa-1;txy.y=bb-1;
              po.push_back(txy);
          }
        int mark=1;
       for(int i=0;i<k+1;i++)
        for(int j=i+1;j<k+1;j++)
           {
               mindis[j][i]=mindis[i][j]=bfs(i,j);
               if(mindis[i][j]==-1)
                {
                   mark=0;break;
                }
           }
        if(mark==0)
        {
            printf("-1\n");continue;
        }
       memset(vis2,0,sizeof(vis2));
       dfs(0,0,0);
       printf("%d\n",mins);
    }
}


hdu 4771 求一点遍历所有给定点的最短路(bfs+dfs)