WuliWuliiii
凤兮凤兮归故乡 遨游四海求其凰

题目链接

  题意:有一个N*M的图,图上有这样的几种情况:

  1. ‘#’,此点为不可达到的点
  2. 小写字母,此点有陷进,进去一次就会扣(小写字母-'a'+1)的血
  3. 大写字母,有怪兽,如果你走到了怪兽点的毗邻的一个点,怪兽就会冲过来打你了,然后怪兽就死了,于是你会扣(大写字母-'A'+1)的血
  4. 其他情况是安全的

  题目要我们求的是:扣血最少的情况下的最短路径。

  于是,就需要考虑一点,就是怪兽你打过一次就打死了,所以再经过这附近的点就不需要再打它了,又有很明显一点就是走回头路肯定不是最优的,所以肯定是走过不再回来了的。

  根据以上的信息,我们如此处理:

  分类讨论:怪物节点非怪物节点

  如果它是怪物节点,那么我们需要跳过它,怪物节点有上下左右四个毗邻的方向点,那么每个方向的点向另外三个方向的点各自建一条路径长度为2的,扣血值为终点需要受到的怪兽伤害的值,其中需要避免在起点附近的怪兽造成的旧伤害。

  否则,它是非怪物节点,那么直接考虑它到毗邻的非怪物节点的情况了,为什么不考虑它到毗邻的怪物节点的情况呢?上面已经考虑过了。所以,直接考虑为长度为1,扣血值为终点受到怪物伤害的值,这样的一条边。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <string>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <limits>
  8 #include <vector>
  9 #include <stack>
 10 #include <queue>
 11 #include <set>
 12 #include <map>
 13 #include <bitset>
 14 #include <unordered_map>
 15 #include <unordered_set>
 16 #define lowbit(x) ( x&(-x) )
 17 #define pi 3.141592653589793
 18 #define e 2.718281828459045
 19 #define INF 0x3f3f3f3f
 20 #define HalF (l + r)>>1
 21 #define lsn rt<<1
 22 #define rsn rt<<1|1
 23 #define Lson lsn, l, mid
 24 #define Rson rsn, mid+1, r
 25 #define QL Lson, ql, qr
 26 #define QR Rson, ql, qr
 27 #define myself rt, l, r
 28 #define pii pair<int, int>
 29 #define MP(a, b) make_pair(a, b)
 30 using namespace std;
 31 typedef unsigned long long ull;
 32 typedef unsigned int uit;
 33 typedef long long ll;
 34 const int dir[4][2] =
 35 {
 36     -1, 0,
 37     0, -1,
 38     0, 1,
 39     1, 0
 40 };
 41 const int maxN = 505;
 42 int N, M;
 43 char mp[maxN][maxN];
 44 inline bool In_Map(int x, int y) { return x >= 1 && y>= 1 && x <= N && y <= M && mp[x][y] ^ '#'; }
 45 struct Edge
 46 {
 47     int nx, ny, hp, step;
 48     Edge(int a=0, int b=0, int c=0, int d=0):nx(a), ny(b), hp(c), step(d) {}
 49 };
 50 vector<Edge> to[maxN][maxN];
 51 void addEddge(int x, int y, int nx, int ny, int hp, int step) { to[x][y].push_back(Edge(nx, ny, hp, step)); }
 52 void Creat_Graph()
 53 {
 54     for(int x=1; x<=N; x++)
 55     {
 56         for(int y=1; y<=M; y++)
 57         {
 58             if(!In_Map(x, y)) continue;
 59             if(isupper(mp[x][y]))
 60             {
 61                 for(int i=0, x1, y1; i<4; i++)
 62                 {
 63                     x1 = x + dir[i][0]; y1 = y + dir[i][1];
 64                     if(!In_Map(x1, y1)) continue;
 65                     for(int j=0, x2, y2, hp; j<4; j++)
 66                     {
 67                         if(i == j) continue;
 68                         x2 = x + dir[j][0]; y2 = y + dir[j][1];
 69                         if(!In_Map(x2, y2)) continue;
 70                         hp = 0;
 71                         for(int k=0, x3, y3; k<4; k++)
 72                         {
 73                             x3 = x2 + dir[k][0]; y3 = y2 + dir[k][1];
 74                             if(!In_Map(x3, y3)) continue;
 75                             if(isupper(mp[x3][y3]) && abs(x3 - x1) + abs(y3 - y1) > 1) hp += mp[x3][y3] - 'A' + 1;
 76                         }
 77                         addEddge(x1, y1, x2, y2, hp, 2);
 78                     }
 79                 }
 80             }
 81             else
 82             {
 83                 for(int i=0, x1, y1, hp; i<4; i++)
 84                 {
 85                     x1 = x + dir[i][0]; y1 = y + dir[i][1];
 86                     if(!In_Map(x1, y1) || isupper(mp[x1][y1])) continue;
 87                     hp = 0;
 88                     for(int j=0, x2, y2; j<4; j++)
 89                     {
 90                         x2 = x1 + dir[j][0]; y2 = y1 + dir[j][1];
 91                         if(!In_Map(x2, y2)) continue;
 92                         if(isupper(mp[x2][y2])) hp += mp[x2][y2] - 'A' + 1;
 93                     }
 94                     addEddge(x, y, x1, y1, hp, 1);
 95                 }
 96             }
 97         }
 98     }
 99 }
100 struct node
101 {
102     int x, y; pii val;
103     node(int a=0, int b=0, pii c=MP(0, 0)):x(a), y(b), val(c) {}
104     friend bool operator < (node e1, node e2) { return e1.val.first == e2.val.first ? e1.val.second > e2.val.second : e1.val.first > e2.val.first; }
105 } now;
106 priority_queue<node> Q;
107 int sx, sy, tx, ty;
108 pii dis[maxN][maxN];
109 void Dijkstra()
110 {
111     while(!Q.empty()) Q.pop();
112     for(int i=1; i<=N; i++) for(int j=1; j<=M; j++) dis[i][j] = MP(INF, INF);
113     dis[sx][sy] = MP(0, 0);
114     Q.push(node(sx, sy, MP(0, 0)));
115     int x, y, xx, yy; pii val, nex_val;
116     while(!Q.empty())
117     {
118         now = Q.top(); Q.pop();
119         x = now.x; y = now.y; val = now.val;
120         if(x == tx && y == ty) { printf("%d %d\n", now.val.first, now.val.second); return; }
121         if(dis[x][y] < now.val) continue;
122         for(Edge V : to[x][y])
123         {
124             xx = V.nx; yy = V.ny;
125             nex_val.first = val.first + V.hp;
126             nex_val.second = val.second + V.step;
127             if(islower(mp[xx][yy])) nex_val.first += mp[xx][yy] - 'a' + 1;
128             if(dis[xx][yy] > nex_val)
129             {
130                 dis[xx][yy] = nex_val;
131                 Q.push(node(xx, yy, nex_val));
132             }
133         }
134     }
135 }
136 int main()
137 {
138     int T; scanf("%d", &T);
139     while(T--)
140     {
141         scanf("%d%d", &N, &M);
142         scanf("%d%d%d%d", &sx, &sy, &tx, &ty);
143         for(int i=1; i<=N; i++) scanf("%s", mp[i] + 1);
144         for(int i=1; i<=N; i++) for(int j=1; j<=M; j++) to[i][j].clear();
145         Creat_Graph();
146         Dijkstra();
147     }
148     return 0;
149 }

 

posted on 2020-10-06 10:34  唔哩Wulili  阅读(157)  评论(0编辑  收藏  举报