FDU--- (bfs+dfs 未完待补充)

D - 小明的迷宫

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64u

Submit Status

Description

小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫。因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷宫。

Input

有多组测试数据。

每组数据第一行给出两个正整数n,m(0<n,m<=100)。代表迷宫的长和宽。

接着n行,每行m个整数。正数代表财宝(财宝的个数不超过10);负数代表墙,无法通过;0代表通道。

每次移动到相邻的格子,所花费的时间是1秒。小明只能按上、下、左、右四个方向移动。

小明的初始位置是(1,1)。迷宫的出口也在(1,1)。

Output

输出获得所有财宝并逃出迷宫所花费的最小时间,如果无法完成目标则输出-1。

Sample Input

3 30 0 00 100 00 0 02 21 11 1

Sample Output

44

求解旅行商(TSP)问题,一般有三个方法,dp,或者回溯或者什么分之限界啥啥的,不太懂,参考了下别人的方法,其他的方法以后再说,回溯的方法是,先求出各个宝藏(加上起点)间的最短路,因为最多10个宝藏,再用次DFS回溯更新出从起点开始遍历过且仅遍历一次的最小路径。

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxd=100+5;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
typedef long long ll;
typedef pair<int,int> pii;
//---------------------------
int dx[]= {0,0,1,-1};
int dy[]= {1,-1,0,0};
typedef struct node
{
    int x,y,t;
    node(int x_ = 0, int y_ = 0, int t_ = 0)
    {
        x = x_;
        y = y_;
        t = t_;
    }
};
int mz[maxd][maxd],vis[maxd][maxd]= {0},path[20][20];
int vist[20];
int cnt,ans,n,m;
vector<node> gold;

void init()
{
    cnt=0;
    ans=INF;
    gold.clear();
    node tmp(1,1,0);
    gold.push_back(tmp);

    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
        {
            scanf("%d",&mz[i][j]);
            if(mz[i][j]>0 && !(i==1 && j==1))
            {
                ++cnt;
                node tmp(i,j,0);
                gold.push_back(tmp);
            }
        }
  //cout<<"gold="<<gold.size()<<endl;
  cnt=gold.size();
    for(int i=0; i<cnt; ++i)
        for(int j=0; j<cnt; ++j)
            path[i][j]=0;
}

bool ok(int x,int y)
{
    if(x<=0 || y<=0 || x>n || y>m) return false;
    return true;
}

int bfs(node a,node b)
{
    vis[a.x][a.y]=1;
    queue<node> q;
    q.push(a);
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(now.x==b.x && now.y==b.y)
        {
            return now.t;
        }

        for(int i=0; i<4; ++i)
        {
            int xx=now.x+dx[i];
            int yy=now.y+dy[i];
            int tt=now.t+1;
            if(ok(xx,yy) && vis[xx][yy]==0 && mz[xx][yy]>=0)
            {
                vis[xx][yy]=1;
                node tmp(xx,yy,tt);
                q.push(tmp);
            }
        }
    }
    return -1;
}

void dfs(int x,int tmpcnt,int t)
{
    if(t>ans) return;
    if(tmpcnt==cnt && path[x][0]!=-1)
    {
        ans=min(ans,t+path[x][0]);
        return;
    }

    for(int i=0; i<cnt; ++i)
    {
        //cout<<i<<endl;
        if(vist[i]==0 && path[x][i]!=-1)
        {
            vist[i]=1;
          //  cout<<"vist1="<<i<<endl;
            dfs(i,tmpcnt+1,path[x][i]+t);
          //  cout<<"vist2="<<i<<endl;
            vist[i]=0;
        }
    }
}

int main()
{
    freopen("1.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(int i=0; i<cnt; ++i)
            for(int j=i+1; j<cnt; ++j)
            {
                mem(vis,0);
                path[i][j]=path[j][i]=bfs(gold[i],gold[j]);

            }
//          for(int i=0; i<cnt; ++i)
//            for(int j=i+1; j<cnt; ++j)
//                cout<<i<<' '<<j<<' '<<path[i][j]<<endl;
//            cout<<endl;

        mem(vist,0);
        dfs(0,0,0);
        if(mz[1][1]<0) {printf("-1\n");continue;}
        if(ans==INF)
            printf("-1\n");
        else
            printf("%d\n",ans);

    }
    return 0;
}
时间: 2024-10-27 08:21:14

FDU--- (bfs+dfs 未完待补充)的相关文章

BFS/DFS算法介绍与实现(转)

广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索.其中有很多的算法都用到了这两种思想,比如:Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想.BFS的思想:从一个图的某一个顶点V0出发,首先访问和V0相邻的且未被访问过的顶点V1.V2.--Vn,然后依次访问与V1.V2--Vn相邻且未被访问的顶点.如此继续,找到所要找的顶点或者遍历完整个图.由此

邻结矩阵的建立和 BFS,DFS;;

邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!---------------------------------------------------------------------------------------------------------------------------------------//邻接矩阵的建立和 其BFS, DFS, 遍历 #include <

HDU ACM 1044 Collect More Jewels BFS+DFS

题意:在一个迷宫中,有一些宝物,从起点走到终点,问在给定的时间内,到达终点后所能拾取珠宝的最大价值. 分析(BFS+DFS): 1.求入口到第一个取宝物的地方的最短距离 2.求第i个取宝物的地方到第i+1个取宝物的地方的最短距离 3.求第n个取宝物的地方到出口的最短距离 4.保证以上3点能在时间L内实现的情况下,取得的宝石价值最大. BFS特点:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元来存储状态) DFS特点:对于解决遍历和求所有问题有效,对于问

模板区域[未完待续](会定期的更新哦(有时间就更了))

写这个博客目的就是为了记录下学过的模板方便我这焫鷄复习吧//dalao们绕道 近期学的: (1)来自机房学长jjh大神教的求1~n的所有最小素因数和加上本焫鷄的批注 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath>//求1~n的最小质因数 using namespace std; const int MAXN=1e6+

Codeforces Round #395 (Div. 2)(未完)

2.2.2017 9:35~11:35 A - Taymyr is calling you 直接模拟 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; const int N=1e4+5; inline int read()

Dancing Links 小结 (因为之前丢了一次稿,未完待续)

Dancing Links (DLX)是Knuth为了解决精确覆盖问题而提出的算法,很多搜索问题可以转化位精确覆盖问题从而使用Dancing Links解决(效率会比DFS高很多,因为里面常常蕴涵着意想不到的剪枝) 信息学竞赛中的DLX的问题类似网络流,只需建图+贴版即可 参考文献: 1.DLX的原理:Knuth的论文: 原版:http://arxiv.org/abs/cs/0011047 翻译版:http://wenku.baidu.com/view/d8f13dc45fbfc77da269b

中矿新生赛 H 璐神看岛屿【BFS/DFS求联通块/连通块区域在边界则此连通块无效】

时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 璐神现在有张n*m大小的地图,地图上标明了陆地(用"#"表示)和海洋(用"."表示),现在璐神要计算这张地图上岛屿的数量. 已知岛屿是由陆地的连通块组成,即一块陆地的上.下.左.右,左上,右上,左下,右下有其他陆地,则构成连通块,以此类推. 此外,岛屿的详细定义如下: 1.岛屿的周围必须全是海洋. 2.如果连通块有任意

whatweb.rb 未完待续

#!/usr/bin/env ruby #表示ruby的执行环境 =begin # ruby中用=begin来表示注释的开始 .$$$ $. .$$$ $. $$$$ $$. .$$$ $$$ .$$$$$$. .$$$$$$$$$$. $$$$ $$. .$$$$$$$. .$$$$$$. $ $$ $$$ $ $$ $$$ $ $$$$$$. $$$$$ $$$$$$ $ $$ $$$ $ $$ $$ $ $$$$$$. $ `$ $$$ $ `$ $$$ $ `$ $$$ $$' $ `$

把握linux内核设计思想系列(未完待续......)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 把握linux内核设计思想(一):系统调用 把握linux内核设计思想(二):硬中断及中断处理 把握linux内核设计思想(三):下半部机制之软中断 把握linux内核设计思想(四):下半部机制之tasklet 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择 把握linux内核设计思想(六):内核时钟中断 把握linux内核设计思想(七):内核定时器和