标签:style blog http color io os ar for sp
题意:
一个边长为n的正方形网格图,其中有一些点‘ . ‘表示可达,‘ # ‘表示不可达,你不能走到不可达的点上,以及每一个单位时间你只能走到相邻的网格(上下左右)。现在给你m条密道,每条密道起始位置(x1,y1),终点位置(x2,y2),当你从起点进去后能瞬间从终点位置出来(不花时间),但是每条密道你只能走一遍。现在,你可以选择任意一个可达的点作为起点,问能否在满足条件下走完所有的密道,有解输出最短时间,否则输出-1。
分析:
先用bfs处理出来每个隧道之间的距离,然后就是走的各个隧道之间的顺序,可以用状压dp来做,
dp[ i ][ j ]表示已经经过的密道状态为 i (i为压缩状态,二进制的每一位表示相应的密道是否已经走过,走过为1,否则为0),最后一个经过的密道是j时的最小用时。
状态转移方程为:dp[ i | ( 1 << k ) ][ k ] = min { dp[ i | ( 1 << k ) ][ k ] , dp[ i ][ j ] + dist[ j ][ k ] } 。
其中必须保证dp[ i ][ j ]已经有了的状态,dist[ j ][ k ]不是INF ( j 出发能到达 k ),以及状态 i 中不包含第 k 个密道能才发生转移。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <queue> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 #define LL __int64 9 const int maxn = 20+10; 10 using namespace std; 11 const int INF = 1<<28; 12 char s[maxn][maxn]; 13 int c[maxn][maxn], d[1<<17][20], n; 14 int dx[] = {0, 0, 1, -1}; 15 int dy[] = {1, -1, 0, 0}; 16 struct node 17 { 18 int x, y, step; 19 }pos, ne; 20 int bfs(int a, int b, int c, int d) 21 { 22 queue<node>q; 23 int vis[maxn][maxn], i; 24 memset(vis, 0, sizeof(vis)); 25 ne.x = a; ne.y = b; ne.step = 0; 26 vis[a][b] = 1; 27 q.push(ne); 28 while(!q.empty()) 29 { 30 pos = q.front(); 31 q.pop(); 32 if(pos.x == c && pos.y == d) 33 return pos.step; 34 for(i = 0; i < 4; i++) 35 { 36 ne.x = pos.x+dx[i]; 37 ne.y = pos.y+dy[i]; 38 ne.step = pos.step+1; 39 if(!(ne.x>=1&&ne.x<=n && ne.y>=1&&ne.y<=n)) continue; 40 if(s[ne.x][ne.y]==‘#‘) continue; 41 if(vis[ne.x][ne.y]) continue; 42 q.push(ne); 43 vis[ne.x][ne.y] = 1; 44 } 45 } 46 return INF; 47 } 48 int main() 49 { 50 int m, i, j, k, ans; 51 int x1[maxn], y1[maxn], x2[maxn], y2[maxn]; 52 while(~scanf("%d%d", &n, &m)) 53 { 54 memset(c, 0, sizeof(c)); 55 memset(s, 0, sizeof(s)); 56 for(i = 1; i <= n; i++) 57 { 58 getchar(); 59 for(j = 1; j <= n; j++) 60 scanf("%c", &s[i][j]); 61 } 62 for(i = 0; i < m; i++) 63 cin>>x1[i]>>y1[i]>>x2[i]>>y2[i]; 64 for(i = 0; i < m; i++) 65 for(j = 0; j < m; j++) 66 { 67 if(i == j) continue; 68 c[i][j] = bfs(x2[i], y2[i], x1[j], y1[j]); 69 } 70 for(i = 0; i < (1<<m); i++) 71 for(j = 0; j < m; j++) 72 d[i][j] = INF; 73 74 for(i = 0; i < m; i++) 75 d[1<<i][i] = 0; 76 77 for(i = 0; i < (1<<m); i++) 78 for(j = 0; j < m; j++) 79 if(d[i][j]!=INF) 80 for(k = 0; k < m; k++) 81 { 82 if(!(i&(1<<k)) && c[j][k]!=INF) 83 d[i|(1<<k)][k] = min(d[i|(1<<k)][k], d[i][j]+c[j][k]); 84 } 85 ans = INF; 86 for(i = 0; i < m; i++) 87 ans = min(ans, d[(1<<m)-1][i]); 88 if(ans == INF) printf("-1\n"); 89 else 90 printf("%d\n", ans); 91 } 92 return 0; 93 }
标签:style blog http color io os ar for sp
原文地址:http://www.cnblogs.com/bfshm/p/4032042.html