码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC 2014 Summer Training #3 Div.2

时间:2014-07-19 00:01:21      阅读:269      评论:0      收藏:0      [点我收藏+]

标签: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最多并且
在终点时该状态可达,对应的值即为答案。若在终点处所有状态都不可达,则无解。
【代码】:

bubuko.com,布布扣
  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 }
View Code

(更新中)

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!