hdu4856(bfs + 状态压缩)
来源:互联网 发布:东京 泡泡 上门 知乎 编辑:程序博客网 时间:2024/05/21 22:21
题意:一个n*n的网格,"#"表示障碍物,m个隧道,每个隧道都有个出口和入口,为走遍所有隧道的最短时间,一分钟走一个网格。绝对是到好题,N很少,一开始用bfs+dfs做,超时了,因为dfs时的时间复杂度是15!。
解题思路:把模型转换一下就变成了,n个隧道,每个隧道之间的距离为c[i][j](这个是通过bfs求出来的),然后就用状态压缩DP解,dp[i][j]表示当前状态为i所在的隧道是j,
状态转移dp[(1<<k)+j][k] = min(dp[(1<<k)+j][k],c[i][j]+dp[i][j]),然后初始化dp为inf,dp[1<<i][i] = 0。到这里题目就可以做出来了
代码如下:
#include<iostream>#include<algorithm>#include<queue>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#define N 20#define inf 0x3f3f3f3f#define pi acos(-1.0)#define eps 10e-6using namespace std;char a[N][N];struct node{ int x,y;}s[N],e[N];int dp[1<<16][N];queue<node> q;int vis[N][N];int tag[N];int n,m,ans,flag;int c[N][N];int dist[N][N];int d[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};void bfs(int x,int y)//求每个隧道出口到其他隧道入口的最近距离{ for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) dist[i][j] = inf; memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); node temp; temp.x = x; temp.y = y; q.push(temp); vis[x][y] = 1; dist[x][y] = 0; while(!q.empty()) { node now = q.front(); q.pop(); int i; for(i = 0; i < 4; i++) { int tempx = now.x + d[i][0]; int tempy = now.y + d[i][1]; temp.x = tempx; temp.y = tempy; if(tempx < 0 || tempx >= n || tempy < 0 || tempy >= n || vis[tempx][tempy] || a[tempx][tempy] == '#') continue; vis[tempx][tempy] = 1; dist[tempx][tempy] = dist[now.x][now.y]+1; q.push(temp); } }}int main(){ while(scanf("%d%d",&n,&m) != EOF) { int i, j,k; for(i = 0; i < n; i++) scanf("%s",a[i]); for(i = 0; i < m; i++){ scanf("%d%d%d%d",&s[i].x,&s[i].y,&e[i].x,&e[i].y); s[i].x--;s[i].y--;e[i].x--;e[i].y--; } memset(c,0,sizeof(c)); for(i = 0; i < m; i++) { bfs(e[i].x,e[i].y); for(j = 0; j < m; j++) if(i != j) c[i][j] = dist[s[j].x][s[j].y]; } for(i = 0; i < (1<<m); i++) for(j = 0; j < m; j++) dp[i][j] = inf;//注意初始化 for(i = 0; i < m; i++) dp[1<<i][i] = 0; for(i = 0; i < (1<<m); i++)//关键在这里 for(j = 0; j < m; j++) if(i&(1<<j)) for(k = 0; k < m; k++) { if(k == j) continue; if((i&(1<<k)) == 0) dp[i+(1<<k)][k] = min(dp[i+(1<<k)][k],c[j][k]+dp[i][j]); } int ans = inf; for(i = 0; i < m; i++) if(dp[(1<<m)-1][i] < ans) ans = dp[(1<<m)-1][i]; if(ans >= inf) printf("-1\n"); else printf("%d\n",ans); } return 0;}
0 0
- hdu4856(bfs + 状态压缩)
- hdu4856(状态压缩)
- Hdu4856 bfs+状压dp
- hdu5025(bfs,状态压缩)
- 状态压缩(1)--hdu5094(状态压缩+bfs)(能力题)
- hdu1429(bfs利用状态压缩)
- hdu4771 水搜索(状态压缩+bfs)
- hdu1885Key Task(状态压缩+bfs)
- hdu 1429 (bfs+状态压缩)
- hdu 5094 Maze (bfs+状态压缩)
- [HDU]5094Maze(状态压缩BFS)
- HDU 5094 Maze(BFS、状态压缩)
- Flip Game(状态压缩+BFS)
- POJ1324 Holedox Moving(状态压缩+BFS)
- poj 1324(BFS+状态压缩)
- POJ1753 状态压缩(+BFS) + 棋盘问题
- hdu1885Key Task (BFS+状态压缩)
- HDU 1429 (BFS+状态压缩)
- Python(2.7.x)多线程的简单示例
- poj1182 并查集经典题 Weighted Union-Find Sets
- jquery中的冒泡事件
- AbstractAccountAuthenticator简介
- hdu 1880 二分+快排 水题
- hdu4856(bfs + 状态压缩)
- 1-100的素数
- ACM中的java使用
- UVa10129 Play on Words
- FTP文件传输协议
- 你值得拥有的数值计算软件 —— Octave
- Spark参数调优&&Tricks
- Android中保存图片的两种方式
- codeforces 461A Appleman and Toastman