hdu4856(bfs + 状态压缩)
2014-09-03 20:05
197 查看
题意:一个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。到这里题目就可以做出来了
代码如下:
解题思路:把模型转换一下就变成了,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-6 using namespace std; char a ; struct node { int x,y; }s ,e ; int dp[1<<16] ; queue<node> q; int vis ; int tag ; int n,m,ans,flag; int c ; int dist ; 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; }
相关文章推荐
- HDU 1885 Key Task (BFS + 状态压缩)
- HDU 3247 Resource Archiver AC自动机 + bfs + 状态压缩dp
- ZOJ 1301 The New Villa (BFS + 状态压缩)
- (HDU 1429)胜利大逃亡(续) BFS + 二进制状态压缩
- hdoj 1429 胜利大逃亡(续)< BFS + 状态压缩>
- UVa 321 The New Villa ( BFS + 状态压缩判重)
- HDU - 5067 Harry And Dig Machine (bfs + 状态压缩)
- hdoj 1429 胜利大逃亡(续) 【BFS + 状态压缩】
- HDOJ 1429 胜利大逃亡(续)(BFS + 状态压缩)
- hdu 1429 胜利大逃亡(续) (bfs + 状态压缩)
- hdu 2209 BFS + 状态压缩
- BFS + 状态压缩 POJ 2965 The Pilots Brothers' refrigerator
- POJ 2688 Cleaning Robot(BFS + A* + 状态压缩DP)
- hdu 1429 胜利大逃亡(续) (bfs + 状态压缩)
- hdu4856(状态压缩)
- BFS + 状态压缩 POJ 2965 The Pilots Brothers' refrigerator
- HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)
- POJ 1324(BFS + 状态压缩)
- HDOJ 4771 Stealing Harry Potter's Precious(bfs + 状态压缩)
- POJ 1324(BFS + 状态压缩)