标签:style blog http color strong os
(更新中)
A:ZOJ 3611 BFS+状态压缩
【题意】:
给定一张n*m的图,图上每个点有如下情况:
L,R,D,U:代表在该点上只能往它已经给定的方向前进。
#,W:不能走到该点。
$:走到该点,可以花两分钟得到一分值,然后可以从该点向任意方向走。
0:走到该点后可以向任意方向走。
然后给你起点和终点坐标,问是否能从起点走到终点,如果能,求出可获得的最大分值以及与之对应达到该最大分值所需的的最小时间花
费。(其中起点和终点坐标可以相同)
【知识点】:
BFS+状态压缩
【题解】:
我觉得超级棒的题!真心感觉涨姿势了。
几个关键处理:
1、对图的转换,重新建模。先取出所有可以往任意方向行走的点并为之标号(因为这两者加起来的和也只是区区110而已)。然后找离该
点最近的能自由方向行走的点并求其时间,然后连边(时间为该边的权值)。(邻接矩阵就这样变成一个小巧的邻接表了)
2、状态转移部分。用dp[u][state]记录当从起点走到点u(这里的u指的是转换后得到的邻接表的点)得到财宝的状态为state时所需要的
最小时间花费。显然有初始状态dp[st][0] = 0,st为起点,其它状态设为不可达。利用bfs求出dp的解。然后在终点处找状态中1最多并且
在终点时该状态可达,对应的值即为答案。若在终点处所有状态都不可达,则无解。
【代码】:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <iomanip> 9 #include <string> 10 #include <vector> 11 #include <cstring> 12 #include <sstream> 13 #include <iostream> 14 #include <fstream> 15 #include <algorithm> 16 #include <bitset> 17 #include <climits> 18 #include <ostream> 19 #include <ios> 20 #include <cstdlib> 21 using namespace std; 22 23 #define wh while 24 #define inf (int)(~0u/2) 25 #define FOR(i, n) for(int i = 0; i < n; i++) 26 #define FOR1(i, n) for(int i = 1; i < n; i++) 27 #define FOR2(i, n) for(int i = 0; i <= n; i++) 28 #define REP(i,n) for(int i = 1; i <= n; i++) 29 #define FORI(it,n) for(typeof(n.begin()) it = n.begin(); it != n.end(); it++) 30 #define sf scanf 31 #define pf printf 32 #define frs first 33 #define sec second 34 #define psh push_back 35 #define mkp make_pair 36 #define PB(x) push_back(x) 37 #define MP(x, y) make_pair(x, y) 38 #define clr(abc,z) memset(abc,z,sizeof(abc)) 39 #define lt(v) v << 1 40 #define rt(v) v << 1 | 1 41 #define mid ((l + r) >> 1) 42 #define lson l, mid, v << 1 43 #define rson mid + 1, r, v << 1 | 1 44 45 #define fre freopen("1.txt", "r", stdin) 46 47 typedef long long LL; 48 typedef long double LD; 49 50 const int maxn = 550; 51 const int bt = 2100; 52 const int smaxn = 220; 53 const int INF = 1061109567; 54 55 int dp[smaxn][bt]; 56 bool inq[smaxn][bt]; 57 58 struct EDGE{ 59 int v, w; 60 }; 61 struct NODE{ 62 int id; int state; 63 NODE(){} 64 NODE(int x, int y){ 65 id = x; state = y; 66 } 67 }; 68 int dx[] = {0, 1, 0, -1}; 69 int dy[] = {1, 0, -1, 0}; 70 71 int n, m; int num1, num2; 72 vector<EDGE> G[maxn]; 73 int stx, sty, edx, edy; 74 char s[maxn][maxn]; 75 int id[maxn][maxn]; 76 bool vis[maxn][maxn]; 77 78 void init(){ 79 clr(id, -1); 80 num1 = num2 = 0; 81 FOR(i, smaxn) G[i].clear(); 82 FOR(i, n) 83 sf("%s", s[i]); 84 sf("%d%d%d%d", &stx, &sty, &edx, &edy); 85 stx--; sty--; edx--; edy--; 86 } 87 bool isOK(int x, int y){ 88 if(x >= 0 && x < n && y >= 0 && y < m 89 && s[x][y] != ‘W‘ && s[x][y] != ‘#‘) 90 return true; 91 return false; 92 } 93 void add(int u, int v, int w){ 94 EDGE tmp; tmp.v = v; tmp.w = w; 95 G[u].PB(tmp); 96 } 97 int getnear(int x, int y, int& t){ 98 clr(vis, 0); 99 wh(s[x][y] != ‘0‘ && s[x][y] != ‘$‘){ 100 t++; 101 if(s[x][y] == ‘L‘) y--; 102 else if(s[x][y] == ‘R‘) y++; 103 else if(s[x][y] == ‘U‘) x--; 104 else if(s[x][y] == ‘D‘) x++; 105 if(!isOK(x, y)) return -1; 106 if(vis[x][y]) return -1; 107 vis[x][y] = true; 108 } 109 return id[x][y]; 110 } 111 int getlong1(int x){ 112 int ans = 0; 113 wh(x){ 114 if(x & 1) ans++; 115 x >>= 1; 116 } 117 return ans; 118 } 119 120 121 int main(){ 122 wh(sf("%d%d", &n, &m) != EOF){ 123 init(); 124 FOR(i, n) FOR(j, m) 125 if(s[i][j] == ‘$‘) id[i][j] = num1++; 126 num2 = num1; 127 FOR(i, n) FOR(j, m) 128 if(s[i][j] == ‘0‘) id[i][j] = num2++; 129 FOR(i, n) FOR(j, m) 130 if(id[i][j] != -1){ 131 int u = id[i][j]; 132 FOR(k, 4){ 133 int tx = i + dx[k]; int ty = j + dy[k]; 134 int tm = 1; 135 if(isOK(tx, ty)){ 136 int v = getnear(tx, ty, tm); 137 if(v != -1) 138 add(u, v, tm); 139 } 140 } 141 } 142 int idst = id[stx][sty]; int ided = id[edx][edy]; 143 144 queue<NODE> Q; 145 wh(!Q.empty()) Q.pop(); Q.push(NODE(idst, 0)); 146 clr(dp, 0x3f); clr(inq, 0); 147 dp[idst][0] = 0; inq[idst][0] = true; 148 wh(!Q.empty()){ 149 int u = Q.front().id; 150 int state0 = Q.front().state; Q.pop(); 151 inq[u][state0] = false; 152 int ns, nt, nv; 153 FOR(i, (int)G[u].size()){ 154 ns = state0; nt = dp[u][state0]; 155 nv = G[u][i].v; nt += G[u][i].w; 156 if(nv < num1 && (((1 << nv) & ns) == 0)){ 157 nt += 2; ns |= (1 << nv); 158 } 159 if(dp[nv][ns] > nt){ 160 dp[nv][ns] = nt; 161 if(!inq[nv][ns]){ 162 Q.push(NODE(nv, ns)); 163 inq[nv][ns] = true; 164 } 165 } 166 } 167 } 168 int ans = INF, ft = -1; 169 FOR(i, (1 << num1)){ 170 int btlong = getlong1(i); 171 if(btlong > ft && dp[ided][i] < INF){ 172 ans = dp[ided][i]; ft = btlong; 173 } 174 } 175 if(ans == INF) pf("-1\n"); 176 else pf("%d\n", ans); 177 } 178 }
(更新中)
UESTC 2014 Summer Training #3 Div.2,布布扣,bubuko.com
UESTC 2014 Summer Training #3 Div.2
标签:style blog http color strong os
原文地址:http://www.cnblogs.com/Ntcrush/p/3849885.html