最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter
来源:互联网 发布:dbc数据库怎么打开 编辑:程序博客网 时间:2024/06/05 17:46
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4568
题目大意:
给一个矩阵 n*m (n m<=200),方格里如果是0~9表示通过它时要花费的代价,-1表示不能通过它。
矩阵中有k(k<=13)个珠宝,问从任意外边框出发取走所有珠宝并求走出矩阵的最小的代价。
解题思路:
先dij预处理每一个珠宝到其他其他珠宝的最小花费,不包括自己的花费。然后就是裸的TSP问题了,状态压缩dp即可。
dp[i][j]表示最后到达第i个珠宝,且访问珠宝的状态为j时,最小的花费。
dd[i][j]表示珠宝i到珠宝j之间的花费,注意此时包括j的花费不包括i的花费。
对于已求出的每一种珠宝状态更新后面未求出珠宝的状态。
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/struct Node{ int id,dis; //Node(){} Node(int x,int y) { id=x,dis=y; } friend bool operator <(const struct Node &a,const struct Node &b) { return a.dis>b.dis; //按距离从小到达排序,便于优先队列找到距离当前宝藏的最小距离 }};#define Maxn 220int dd[20][20];//两个宝藏之间的距离int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};int istr[Maxn][Maxn]; //表示珠宝的标号int sa[Maxn][Maxn],cost[20];//cost[i]表示i宝藏到边界的最短距离int n,m,k,hash[20],dp[20][1<<15];int tmpdis[Maxn*Maxn];//其他宝藏距离当前宝藏的距离bool vis[Maxn][Maxn];bool isbor(int x,int y) //是否为边界{ if(x==0||x==n-1||y==0||y==m-1) return true; return false;}bool iscan(int x,int y) //是否在矩阵内部{ if(x<0||x>=n||y<0||y>=m) return false; return true;}void dij(int hh,int cur) //迪杰斯特拉算法求{ memset(tmpdis,INF,sizeof(tmpdis)); memset(vis,false,sizeof(vis)); vis[hh/m][hh%m]=true; priority_queue<Node>myq; tmpdis[hh]=0; myq.push(Node(hh,0)); while(!myq.empty()) { Node tmp=myq.top(); //把距离当前宝藏距离最小的位置找到 myq.pop(); int tt=tmp.id; int x=tt/m,y=tt%m; if(isbor(x,y)) //如果是边界,更新边界 cost[cur]=min(cost[cur],tmp.dis); if(istr[x][y]!=-1) //如果是其他珠宝,更新两珠宝之间的距离 dd[cur][istr[x][y]]=tmp.dis; for(int i=0;i<4;i++) //能走 { int xx=x+dir[i][0],yy=y+dir[i][1]; if(!iscan(xx,yy)||vis[xx][yy]) continue; if(sa[xx][yy]==-1) continue; vis[xx][yy]=true; int temp=xx*m+yy; tmpdis[temp]=min(tmpdis[temp],tmp.dis+sa[xx][yy]); myq.push(Node(temp,tmpdis[temp])); } }}int main(){ int t,a,b; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&sa[i][j]); scanf("%d",&k); memset(istr,-1,sizeof(istr)); for(int i=0;i<k;i++) { scanf("%d%d",&a,&b); istr[a][b]=i; hash[i]=a*m+b; //将坐标从二维转化成一维便于处理 } memset(dd,INF,sizeof(dd)); for(int i=0;i<k;i++) //求出每一个宝藏到其他宝藏的距离 { cost[i]=INF; dd[i][i]=0; //宝藏从自己到自己距离为0 dij(hash[i],i); //找到从i到所有的宝藏的最短距离 //printf("i:%d cost:%d\n",i,cost[i]); } memset(dp,INF,sizeof(dp)); for(int i=0;i<k;i++) { //dp[i][1<<i]是包括i本身花费的,+进来花费cost[i] dp[i][1<<i]=cost[i]+sa[hash[i]/m][hash[i]%m]; // printf("i:%d dp[i][1<<i]:%d\n",i,dp[i][1<<i]); } int lim=1<<k; for(int i=0;i<lim;i++) { for(int j=0;j<k;j++) { if(!(i&(1<<j))) //如果没有经过第j个珠宝 continue; if(dp[j][i]==INF) //此状态无效 continue; for(int p=0;p<k;p++) { if(i&(1<<p)) //p没有经过 continue; if(dd[j][p]==INF) continue; //最后经过的变成了p 依据j->p 更新后面的状态 dp[p][i|(1<<p)]=min(dp[p][i|(1<<p)],dp[j][i]+dd[j][p]); }//dp[j][i]是已经求得的状态了 } } int ans=INF; for(int i=0;i<k;i++) { // printf("%d %d\n",i,dp[i][lim-1]); ans=min(ans,dp[i][lim-1]+cost[i]); //从最短路走出去 } printf("%d\n",ans); } return 0;}
- 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter
- HDU-4568 Hunter 最短路 + 状态压缩DP(TSP)
- Hdu 4568 Hunter【spfa最短路 tsp状态压缩】
- HDU 4568 Hunter 最短路+状压DP
- 旅行商问题 (状态压缩DP)
- hdu 4568 Hunter (旅行商问题)
- hdu 4568 Hunter (旅行商问题)
- HDU 4568 Hunter (状态压缩)
- HDU 4640 Island and study-sister(状态压缩DP+路径压缩)经典 旅行商问题
- 旅行商问题(状态压缩dp)
- 旅行商问题(状态压缩dp)
- [ZOJ 2963] Treasure Hunter [最短路+状态压缩]
- 三进制状态压缩DP(旅行商问题TSP)HDU3001
- HDU3768 Shopping(状态压缩DP+spfa)旅行商问题
- 旅行商问题(状态压缩的DP)
- hdu 4568 spfa 最短路算法+旅行商问题
- HDU 4568 Hunter ( TSP + 状态压缩 )
- HDU 4568 Hunter ( TSP + 状态压缩 )
- Linux CentOS 6.x 开发配置文档 - Nginx
- 三步搞定android单元测试
- zoj 1082 Stockbroker Grapevine
- Android Activity模仿dialog启动
- 用户界面线程AfxBeginThread的使用
- 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter
- birt session 过期问题,跨域问题
- rcp新建工程没有图标的问题解决方案
- 高精度计时器
- __FUNCSIG__ __FUNCDNAME__ __FUNCTION__ __func__
- hdu 1061 数学
- struts2源码分析-IOC容器的实现机制(下篇)
- linux Qt进行qwt的安装与使用
- hessian (Java 篇)