题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4856

题目大意:有一个迷宫。迷宫里有些隧道,每个隧道有起点和终点,在隧道里不耗时。出隧道就耗时,你的任务是访问完所有隧道且仅一次,求最短耗时。

解题思路

暑假练习的时候。把英文读了N遍也没理解题意。

其实就是个最后不回到开头的TSP。

首先求BFS求两两隧道之间的最短路,注意BFS的起点是隧道i的终点,BFS的终点是隧道j的起点。

一定要特判一下两个隧道终点和起点是否一样,如果一样话dis=0, 我因为BFS没注意这个WA了10几次。

PS. 根据esxgx大神的说法,所有最短路算法(Dijkstra or Bellman-Ford)在每两个点距离为1的时候都会退化成普通的BFS,于是你在这里相当于手艹了个最短路。

然后就是对所有隧道进行TSP。

dp[i][j]表示状态i时,在j点的最少耗时,然后就是赤裸裸的TSP了。TSP的写法不唯一,我从别人那扒的这种TSP稍微快点。

#include "cstdio"
#include "string"
#include "iostream"
#include "cstring"
#include "queue"
#include "vector"
using namespace std;
int n,m,vis[][],dis[][],dir[][]={-,,,,,-,,},ans,dp[<<][];
char map[][];
const int inf=0x3f3f3f3f;
struct status
{
int x,y,dep;
status(int x,int y,int dep):x(x),y(y),dep(dep) {}
};
struct tunnel
{
int sx,sy,ex,ey;
}T[];
int bfs(status a,status b)
{
if(a.x==b.x&&a.y==b.y) return ; //关键一步,如果两个隧道恰好拼在一起,则dis=0
memset(vis,,sizeof(vis));
int ans=inf;
queue<status> Q;
Q.push(a);
vis[a.x][a.y]=true;
while(!Q.empty())
{
status t=Q.front();Q.pop();
for(int s=;s<;s++)
{
int X=t.x+dir[s][],Y=t.y+dir[s][];
if(X<||X>n||Y<||Y>n||vis[X][Y]||map[X][Y]!='.') continue;
vis[X][Y]=true;
if(X==b.x&&Y==b.y) {ans=min(ans,t.dep+);return ans;}
Q.push(status(X,Y,t.dep+));
}
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
string tt;
while(cin>>n>>m)
{
memset(dis,,sizeof(dis));
for(int i=;i<=n;i++)
{
cin>>tt;
for(int j=;j<tt.size();j++) map[i][j+]=tt[j];
}
for(int i=;i<=m;i++)
cin>>T[i].sx>>T[i].sy>>T[i].ex>>T[i].ey;
for(int i=;i<=m;i++)
for(int j=;j<=m;j++)
{
if(i==j) {dis[i][j]=;}
else dis[i][j]=bfs(status(T[i].ex,T[i].ey,),status(T[j].sx,T[j].sy,));
}
int cnt=<<m,res=inf;
for(int i=;i<cnt;i++)
{
for(int j=;j<=m;j++)
{
int s=(<<(j-));
if((i&s)==) continue;
if(i==s) dp[i][j]=;
else dp[i][j]=inf;
for(int k=;k<=m;k++)
{
int t=(<<(k-));
if((i&t)==||k==j||dis[k][j]==inf) continue;
dp[i][j]=min(dp[i][j],dp[i^s][k]+dis[k][j]);
}
if(i==cnt-) res=min(res,dp[i][j]);
}
}
if(res==inf) printf("-1\n");
else printf("%d\n",res); }
}
11887989 2014-10-16 20:17:15 Accepted 4856 171MS 2852K 2290 B C++ Physcal

HDU 4856 (状态压缩DP+TSP)的更多相关文章

  1. HDU 5067 (状态压缩DP+TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5067 题目大意:蓝翔挖掘机挖石子.把地图上所有石子都运回起点,问最少耗时. 解题思路: 首先得YY出 ...

  2. HDU 1074 (状态压缩DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...

  3. HDU 3341 状态压缩DP+AC自动机

    题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...

  4. hdu 4284 状态压缩dp

    题意: 有N 个点的无向图,要去其中 h个地点做事,做事需要先办理护照,之后可以挣一定数量的钱,知道了一开始有的总钱数,和 一些城市之间           道路的花费,问可不可以在 指定的 h 个城 ...

  5. hdu 2167 状态压缩dp

    /* 状态转移方程:dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]); */ #include<stdio.h> #include<string ...

  6. BFS+优先队列+状态压缩DP+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=4568 Hunter Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  7. HDU 4640 状态压缩DP 未写完

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640 解题思路: 首先用一个简单的2^n*n的dp可以求出一个人访问一个给定状态的最小花费,因为这i个 ...

  8. 2016"百度之星" - 初赛(Astar Round2A)1002 / HDU 5691 状态压缩DP

    Sitting in Line Problem Description   度度熊是他同时代中最伟大的数学家,一切数字都要听命于他.现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了.游戏的规则十 ...

  9. hdu 4539(状态压缩dp)

    题意:曼哈顿距离是指:|x1-x2|+|y1-y2|,只要知道这个概念题意就懂了. 分析:这道题与前面做的几道题有所不同,因为当前行不仅与前一行有关,而且与前两行有关,所以我们开数组的时候还要记录前两 ...

随机推荐

  1. 暑假热身 A. GCC

    GCC编译器是一个由GNU项目维护的编译系统,它支持多种编程语言的编译.但是它并不包含数学运算符“!”.在数学中,这个符号代表阶乘.表达式n!的意思是从1到n的所有整数的乘积. 例如,4!=4*3*2 ...

  2. CSS clearfix

    The problem happens when a floated element is within a container box, that element does not automati ...

  3. jQuery获取Select选择的Text和 Value(转)

    radio: radio: var item = $('input[name=items][checked]').val(); var item = $('input[name=items]:chec ...

  4. 【转】实战 SSH 端口转发

    本文转自:http://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html,至于有什么用,懂的懂! 实战 SSH 端口转发 通 ...

  5. apache AllowEncodedSlashes 允许URL中对路径分隔符进行编码

    2013年11月29日 10:35:32 情景: 你想通过在当前的URL中记录来源页面的URL,以便处理完请求后再跳转回来源页: http://www.example1.com/refer/http: ...

  6. SQL 查询45题

    表格代码 create table student ( sno ) primary key, sname ) not null, ssex ) not null, sbirthday datetime ...

  7. 查看网卡的流量 iptraf

    yum search iptraf Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds ...

  8. Stringbuffer与Stringbuilder源码学习和对比

    >>String/StringBuffer/StringBuilder的异同 (1)相同点观察源码会发现,三个类都是被final修饰的,是不可被继承的.(2)不同点String的对象是不可 ...

  9. Ubuntu下自动挂载分区

    参考文章:http://feierky.iteye.com/blog/1998602 1.查看分区的UUID sudo blkid /dev/sda1: UUID="3526b254-390 ...

  10. Java Hour 59 JVM Heap

    程序没有方法区释放一段Heap 上的内存,只有JVM 本身可以去回收内存,这个工作单位就是GC. Garbage Collection GC 用来清理对象,同时也用来移动对象减少内存碎片. JVM 指 ...