解题思路:这道题属于图上来回走的问题,可以把重复走的过程弱化,即只强调从u->v的结果,中间经过的节点都不考虑。这道题里面'G','F','Y'是重要的节点,其余的点我们是可以忽略的,也就是说,假设从u->v,我们只需要知道最短路径是多少就可以了,至于是怎么走的,中间绕过了多少个'D'都不是我们关心的。这样我们就只需要用bfs找到'G','F','Y'两两之间的最短路径,剩下的就是一个典型的TSP问题了。对于最小的电池量,可以二分答案,这里很容易想到。在dfs中,我们同样只要知道两点之间的最短路径就可以了,并不需要知道如何走过来的,此外,由于每个'Y'都必须要走到,且数据量较小,所以可以用状态压缩。

对于这种图上来回走的问题,可以把重复走的过程弱化,只强调走的结果。

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>using namespace std;struct edge
{int to,next;
}e[2000];struct node
{int vid,step;
};char mp[20][20];
int id[20][20],c[20][2],head[300],dis[20][20];
int cnt,obj,ids,mid,m,n;
bool mk[20];void init()
{memset(id,-1,sizeof(id));memset(dis,-1,sizeof(dis));memset(head,-1,sizeof(head));cnt=0;ids=1;obj=0;
}void add(int x,int y)
{e[cnt].to=y;e[cnt].next=head[x];head[x]=cnt++;
}void bfs(int x)
{int u,v;node djw,cur,next;queue<node> q;bool vis[400];memset(vis,0,sizeof(vis));djw.vid=x;djw.step=0;q.push(djw);vis[x]=true;while(!q.empty()){cur=q.front();q.pop();u=cur.vid;if(id[u/m][u%m]!=-1)dis[id[x/m][x%m]][id[u/m][u%m]]=cur.step;for(int i=head[u];i!=-1;i=e[i].next){v=e[i].to;if(!vis[v]){vis[v]=true;next.vid=v;next.step=cur.step+1;q.push(next);}}}
}int dfs(int bag,int pos,int sta)
{if((sta&obj)==obj) return 1;for(int i=0;i<ids;i++){if(mk[i] || dis[pos][i]==-1) continue;if(dis[pos][i]<=bag){if(mp[c[i][0]][c[i][1]]=='G'){mk[i]=true;if(dfs(mid,i,sta|(1<<i))) return 1;mk[i]=false;}else{mk[i]=true;if(dfs(bag-dis[pos][i],i,sta|(1<<i))) return 1;mk[i]=false;}}}return 0;
}int main()
{while(scanf("%d%d",&n,&m)!=EOF){if(n==0 && m==0)break;init();for(int i=0;i<n;i++)scanf("%s",mp[i]);for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(mp[i][j]=='D') continue;if(mp[i][j]=='F'){c[0][0]=i;c[0][1]=j;id[i][j]=0;}else if(mp[i][j]=='G'){c[ids][0]=i;c[ids][1]=j;id[i][j]=ids++;}else if(mp[i][j]=='Y'){c[ids][0]=i;c[ids][1]=j;obj|=(1<<ids);id[i][j]=ids++;}if(i-1>=0 && mp[i-1][j]!='D')add(i*m+j,(i-1)*m+j);if(i+1<n && mp[i+1][j]!='D')add(i*m+j,(i+1)*m+j);if(j-1>=0 && mp[i][j-1]!='D')add(i*m+j,i*m+j-1);if(j+1<m && mp[i][j+1]!='D')add(i*m+j,i*m+j+1);}}for(int i=0;i<ids;i++)bfs(c[i][0]*m+c[i][1]);int flag=1;for(int i=1;i<ids;i++){if(mp[c[i][0]][c[i][1]]=='Y' && dis[0][i]==-1){flag=0;break;}}int ans=-1;if(flag){int l=0,r=n*m*(ids-1);while(l<=r){mid=(l+r)>>1;memset(mk,0,sizeof(mk));mk[0]=true;if(dfs(mid,0,1)){ans=mid;r=mid-1;}elsel=mid+1;}}printf("%d\n",ans);}return 0;
}

hdu 3681(bfs+dfs+状态压缩)相关推荐

  1. hdu1429 胜利大逃亡(续) (BFS+简单状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 题目大意:逃离迷宫,但是迷宫里有钥匙和门 题目思路: 关于状态压缩: 1.判断一个数字x二进制下 ...

  2. D - Age of Moyu HDU - 6386 -BFS+DFS分层最短路

    D - Age of Moyu HDU - 6386 题意:双向图,m条边,每条边有一个编号id,而花费就是根据这个id的变化来确定的求1-n的最短路 思路:全值为0,1的图直接bfs按层遍历图找到n ...

  3. uva10160(dfs+状态压缩)

    题意:给出n个点,以及m条边,这些边代表着这些点相连,修一个电力站,若在某一点修一个站,那么与这个点相连的点都可以通电,问所有的点都通电的话至少要修多少个电力站........ 思路:最多给出的是35 ...

  4. 洛谷P1562 还是N皇后(DFS+状态压缩+位运算)

    八皇后问题的介绍在此不再赘述,只贴一下经典八皇后问题的实现代码(参考刘汝佳 <算法竞赛入门经典>) void search(int i) {if(i>n){ans++;return; ...

  5. HDU 4407 Sum(容斥原理+状态压缩)

    题目链接 容斥原理不会,map不会,状态压缩不会.做毛线... 题目大意:给出1-n,n个数,有两个操作1是询问x-y区间上与p互质的数的和是多少,2是改变x位置上的数为c. 自己确实办不了,map这 ...

  6. hdu5025(bfs,状态压缩)

    Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  7. HDU 4332 Constructing Chimney [状态压缩+矩阵]

    烟囱是一个3*3的中空构造,给定烟囱的高度,问用1*1*2的砖头搭成这个烟囱有多少种方法. 首先用一个8位二进制数表示某一层的状态.枚举上下两层的状态,判断这两个状态是否可以相邻,上一层必须将下层填满 ...

  8. HDU - 6749 Mosquito(二分+状态压缩+最大流)

    题目链接:点击查看 题目大意:给出一个 n * m 的房间,再给出 k 个蚊子窝(保证蚊子窝在边界上),每个蚊子窝内有数只蚊子,单位时间内蚊子可以移动一个单位的曼哈顿距离,蚊子们都是非常聪明的,问最少 ...

  9. [HDU 4842]--过河(dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4842 过河 Time Limit: 3000/1000 MS (Java/Others)    Mem ...

最新文章

  1. 以大自然为师,可上天入地的11款仿生机器人
  2. Unbuntu 下安装node 环境
  3. 关于提高代码复用性的几个知识点的回顾
  4. mysql 返回随机行_从mysql数据库返回随机行而不使用rand()
  5. 机器学习术语_机器学习术语神秘化。
  6. Vczh Library++ 语法分析器开发指南
  7. 对比 Ruby 和 Python 的垃圾回收
  8. 编程没点为什么,生活就是十万个为什么
  9. dbvis连接mysql_Dbvis连接Mysql驱动问题
  10. 移动硬盘提示文件或目录损坏且无法读取怎么办
  11. python如何做一个财务报表_用python帮财务小姐姐自动生成财务报表
  12. 日常食物软分类与烹饪方法的思考——预防肥胖
  13. 正版口腔管理软件免费使用,口腔诊所业绩提升就靠它
  14. iOS总结-Runtime篇之用途及面试题的总结一黑魔法Method Swizzling
  15. twitter账户受限_如何为您的企业设置Twitter帐户
  16. Java实现 蓝桥杯 算法训练 未名湖边的烦恼
  17. 编译高博ORBSLAM2_with_pointcloud_map,用TUM数据集测试。
  18. vue过滤器如何使用
  19. WEB开发还有前途吗?
  20. ABAP 基础 -SAP GUI 使用指南

热门文章

  1. 神策数据丨九大行业数字化经营指南集锦,值 100% 收藏
  2. Ian Thiel:靠这 3 点,实现 30 倍增长,从不盈利到营收 5.5 亿
  3. Lind.DDD敏捷领域驱动框架~介绍
  4. Too many links;mkdir
  5. 初学 Delphi 嵌入汇编[12] - 在汇编代码中可以直接使用 Result
  6. ubuntu11.04服务器安装
  7. 初识 ASP.NET 3.5 MVC 开发
  8. 通过APNIC获取各运营商IP网段
  9. 水瓶座和什么座最配:天秤座,双子座,狮子座
  10. shanghai road map and the operational time for 12306 system