hdu3681 PrisonBreak
来源:互联网 发布:mac 移动硬盘绝对路径 编辑:程序博客网 时间:2024/05/18 00:31
一来想用普通BFS实现,无奈超时,怒换思路
遍历所有的点且仅一次,可转化为TSP问题变形
求满足的最小值,显然二分之
遍历所有的点且仅一次,可转化为TSP问题变形
求满足的最小值,显然二分之
推荐一个TSP好的博客,一看就懂 点击打开链接
类似题目: Disney's FastPass hdu4114 hdu4085 Peach Blossom Spring
Accepted3681296MS2372K//#pragma comment(linker, "/STACK:102400000,102400000")//HEAD#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))//STL#define PB push_back//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)#define RS(s) scanf("%s", s)//OUTPUT#define WI(n) printf("%d\n", n)#define WS(s) printf("%s\n", s)typedef long long LL;const int INF = 0x3f3f3f3f;const double eps = 1e-10;const int maxn = 16;const LL MOD = 1e9 + 7;const int F = 1, G = 2, Y = 3;int n, m, cnt, sta, all;struct SWITCH{ short int x, y, kind;}sw[maxn];struct node{ short int x, y, step; node(int a, int b, int s) : x(a), y(b), step(s) {}};char mat[maxn][maxn];int dis[maxn][maxn], dp[maxn][1 << 15], id[maxn][maxn];bool vis[maxn][maxn];int dir[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};void bfs(int th){ CLR(vis, 0); queue<node> Q; vis[sw[th].x][sw[th].y] = 1; dis[th][th] = 0; Q.push(node(sw[th].x, sw[th].y, 0)); while (!Q.empty()) { node t = Q.front(); Q.pop(); REP(i, 4) { int x = t.x + dir[i][0], y = t.y + dir[i][1]; if (x < 0 || x >= n || y < 0 || y >= m || mat[x][y] == 'D') continue; if (!vis[x][y]) { if (id[x][y] != -1) dis[th][id[x][y]] = t.step + 1; vis[x][y] = 1; Q.push(node(x, y, t.step + 1)); } } }}bool ok(int full, int goal){ CLR(dp, -1); dp[sta][1 << sta] = full; REP(s0, all) { REP(i, cnt) { if (dp[i][s0] == -1) continue; if ((s0 & goal) == goal) return 1; REP(j, cnt) { if (s0 & (1 << j)) continue; int ns = s0 | (1 << j); dp[j][ns] = max(dp[j][ns], dp[i][s0] - dis[i][j]); if (dp[j][ns] >= 0 && sw[j].kind == G) dp[j][ns] = full; } } } return false;}void solve(){ CLR(dis, 0x3f); int goal = 0; all = (1 << cnt); REP(i, cnt) bfs(i); REP(i, cnt) if (sw[i].kind != G) goal |= (1 << i); int L = 0, R = n * m * 2; while (L <= R) { int mid = (L + R) >> 1; if (ok(mid, goal)) R = mid - 1; else L = mid + 1; } if (L > n * m * 2) WI(-1); else WI(L);}int main(){ while (~RII(n, m), n || m) { cnt = 0; CLR(id, -1); REP(i, n) { RS(mat[i]); REP(j, m) { if (mat[i][j] == 'F') id[i][j] = cnt, sta = cnt, sw[cnt].kind = F, sw[cnt].x = i, sw[cnt].y = j, ++cnt; else if (mat[i][j] == 'G') id[i][j] = cnt, sw[cnt].kind = G, sw[cnt].x = i, sw[cnt].y = j, ++cnt; else if (mat[i][j] == 'Y') id[i][j] = cnt, sw[cnt].kind = Y, sw[cnt].x = i, sw[cnt].y = j, ++cnt; } } solve(); }}
DFS版本,只对有用节点进行DFS即可
31ms
//#pragma comment(linker, "/STACK:102400000,102400000")//HEAD#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FED(i, b, a) for(int i = (b); i>= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))#define CPY(a, b) memcpy(a, b, sizeof(a))#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)//STL#define SZ(V) (int)V.size()#define PB push_back#define EQ(a, b) (fabs((a) - (b)) <= 1e-10)#define ALL(c) (c).begin(), (c).end()//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)#define RS(s) scanf("%s", s)//OUTPUT#define WI(n) printf("%d\n", n)#define WS(s) printf("%s\n", s)typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 0x3f3f3f3f;const double eps = 1e-10;const int maxn = 16;const LL MOD = 1e9 + 7;const int F = 1, G = 2, Y = 3;int n, m, cnt, sta, all, goal;struct SWITCH{ short int x, y, kind;}sw[maxn];struct node{ short int x, y, step; node(int a, int b, int s) : x(a), y(b), step(s) {}};char mat[maxn][maxn];int dis[maxn][maxn], dp[maxn][1 << 15], id[maxn][maxn];bool vis[maxn][maxn];int dir[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};void bfs(int th){ CLR(vis, 0); queue<node> Q; vis[sw[th].x][sw[th].y] = 1; dis[th][th] = 0; Q.push(node(sw[th].x, sw[th].y, 0)); while (!Q.empty()) { node t = Q.front(); Q.pop(); REP(i, 4) { int x = t.x + dir[i][0], y = t.y + dir[i][1]; if (x < 0 || x >= n || y < 0 || y >= m || mat[x][y] == 'D') continue; if (!vis[x][y]) { if (id[x][y] != -1) dis[th][id[x][y]] = t.step + 1; vis[x][y] = 1; Q.push(node(x, y, t.step + 1)); } } }}bool dfs(int u, int s0, int left, int full){ if ((s0 & goal) == goal) return 1; REP(v, cnt) if (left >= dis[u][v]) { if (s0 & (1 << v)) continue; if (sw[v].kind == G) { if (dfs(v, s0 | (1 << v), full, full)) return 1; } else { if (dfs(v, s0 | (1 << v), left - dis[u][v], full)) return 1; } } return 0;}bool ok(int mid){ return dfs(sta, (1 << sta), mid, mid);}void solve(){ CLR(dis, 0x3f); goal = 0; all = (1 << cnt); REP(i, cnt) bfs(i); REP(i, cnt) if (sw[i].kind == Y && dis[sta][i] == INF) { WI(-1); return; } REP(i, cnt) if (sw[i].kind != G) goal |= (1 << i); int L = 0, R = n * m * 2; while (L <= R) { int mid = (L + R) >> 1; if (ok(mid)) R = mid - 1; else L = mid + 1; } if (L > n * m * 2) WI(-1); else WI(L);}int main(){ while (~RII(n, m), n || m) { cnt = 0; CLR(id, -1); REP(i, n) { RS(mat[i]); REP(j, m) { if (mat[i][j] == 'F') id[i][j] = cnt, sta = cnt, sw[cnt].kind = F, sw[cnt].x = i, sw[cnt].y = j, ++cnt; else if (mat[i][j] == 'G') id[i][j] = cnt, sw[cnt].kind = G, sw[cnt].x = i, sw[cnt].y = j, ++cnt; else if (mat[i][j] == 'Y') id[i][j] = cnt, sw[cnt].kind = Y, sw[cnt].x = i, sw[cnt].y = j, ++cnt; } } solve(); }}
- hdu3681 PrisonBreak
- HDU3681
- prisonbreak图片
- PrisonBreak S2-2-3
- PrisonBreak s2-1
- hdu3681 状压 bfs 二分
- hdu3681 BFS+TSP+二分
- HDU3681 Prison Break【状压】
- prisonbreak照片(2)有新面孔
- hdu3681 状态压缩最优值
- hdu3681之状态压缩dp
- HDU3681 Prison Break(DP)
- hdu3681 Prison Break (dfs+二分+状态压缩)
- HDU3681 Prison Break(状压dp)
- HDU3681 Prison Break(壮压dp+二分+bfs)
- hdu3681(二分+状态压缩dp+bfs)
- 状态压缩DP总结【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- BFS最短路+状态dp(hdu3681)好
- visual studio 2010中搭建Open GL开发环境
- vs2008中构建osg开发环境
- 字符转换异常
- sql server2005配置管理器问题
- vs2008异常
- hdu3681 PrisonBreak
- vs中的类和函数
- putty连接报network error :conncetionrefused
- WebView字号设置
- 使用jsmooth将jar文件转换成可在无java环境中运行的exe文件
- LeetCode题解:Pow(x,n)
- android开发报java.lang.reflect.InvocationTargetException
- onActivityResult的用法
- 对话框控件访问七种方式转自孙鑫