• Gym


    http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contest-bapc-13-en.pdf

    题意:给你一幅图,让两个人从里面走出来的代价最小。经过 . 没有消耗,经过 # 耗费一个代价,* 不能通过。

    思路:比赛时以为是类似于两条路之和最小的那种题,所以没有仔细去想,下来后听了别人提了下思路,也看了下别人的代码,明白了。分两种情况考虑,一种是相遇,一种是不相遇。如果存在不相遇这种答案的话,那结果就是他们俩的最短路之和,相遇的话,就是他们俩到相遇的地方的最短路之和加上相遇的door到外面的最短路减2。这是陈力琪他们队做的,我也是看了他们的代码。

      所以求三遍最短路,第一遍w[i] 表示i这个点到外面的最小代价。第二遍 ds[i] 表示从s(第一个人位置)到i的最小代价,第三遍 dt[i] 表示从t到i的最短路。按照上面的说法得出答案就可以了。

      比较有意思是这里的搜索,因为 . 是不需要代价的,所以在bfs的时候每下一步就直接dfs一次找到下一个#所在的位置再把代价+1入队。在求w[i]的时候,因为距离可能为0,所以得先把边界上的 . 入队,不然w[i]就会求错。

      

      1 #pragma comment(linker, "/STACK:1000000000")
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <fstream>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <deque>
      8 #include <vector>
      9 #include <queue>
     10 #include <string>
     11 #include <cstring>
     12 #include <map>
     13 #include <stack>
     14 #include <set>
     15 #define LL long long
     16 #define MAXN 100005
     17 #define MOD 1000000007
     18 #define INF 0x3f3f3f3f
     19 #define eps 1e-8
     20 using namespace std;
     21 char a[105][105];
     22 int n, m;
     23 int w[10005], ds[10005], dt[10005];
     24 bool vis[105][105];
     25 vector<int> door;
     26 queue<int> Q;
     27 const int step[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
     28 void dfs(int x, int y, int d, int *f){
     29     for (int i = 0; i < 4; i++){
     30         int u = x + step[i][0];
     31         int v = y + step[i][1];
     32         if (vis[u][v] || a[u][v] == '*' || u < 0 || v < 0 || u >= n || v >= m) continue;
     33         f[m * u + v] = d;
     34         vis[u][v] = true;
     35         if (a[u][v] == '#'){
     36             f[m * u + v]++;
     37             Q.push(m * u + v);
     38         }
     39         else{
     40             dfs(u, v, d, f);
     41         }
     42     }
     43 }
     44 void bfs(int *f){
     45     while (!Q.empty()){
     46         int p = Q.front();
     47         int x = p / m, y = p % m;
     48         Q.pop();
     49         //dfs一次相当于代价加一
     50         dfs(x, y, f[m * x + y], f);
     51     }
     52 }
     53 int main()
     54 {
     55 #ifndef ONLINE_JUDGE
     56     freopen("in.txt", "r", stdin);
     57     //freopen("out.txt", "w", stdout);
     58 #endif // OPEN_FILE
     59     int T;
     60     scanf("%d", &T);
     61     while (T--){
     62         scanf("%d%d", &n, &m);
     63         for (int i = 0; i < n; i++){
     64             scanf("%s", &a[i]);
     65         }
     66         memset(w, INF, sizeof(w));
     67         memset(ds, INF, sizeof(ds));
     68         memset(dt, INF, sizeof(dt));
     69         memset(vis, 0, sizeof(vis));
     70         door.clear();
     71         bool apos = false;
     72         int s = 0, t = 0;
     73         for (int i = 0; i < n; i++){
     74             for (int j = 0; j < m; j++){
     75                 if ((i == 0 || j == 0 || i == n - 1 || j == m - 1) && (a[i][j] == '.' || a[i][j] == '$')){
     76                     Q.push(m * i + j);
     77                     w[m * i + j] = 0;
     78                     vis[i][j] == true;
     79                 }
     80             }
     81         }
     82         for (int i = 0; i < n; i++){
     83             for (int j = 0; j < m; j++){
     84                 if (a[i][j] == '*') continue;
     85                 if ((i == 0 || j == 0 || i == n - 1 || j == m - 1) && a[i][j] == '#'){
     86                     w[m * i + j] = 1;
     87                     Q.push(m * i + j);
     88                     vis[i][j] = true;
     89                 }
     90                 if (a[i][j] == '#'){
     91                     door.push_back(m * i + j);
     92                 }
     93                 if (a[i][j] == '$'){
     94                     if (!apos){
     95                         s = m * i + j;
     96                         ds[s] = 0;
     97                         apos = true;
     98                     }
     99                     else{
    100                         t = m * i + j;
    101                         dt[t] = 0;
    102                     }
    103                 }
    104             }
    105         }
    106         bfs(w);
    107         memset(vis, 0, sizeof(vis));
    108         vis[s / m][s % m] = true;
    109         Q.push(s);
    110         bfs(ds);
    111         memset(vis, 0, sizeof(vis));
    112         vis[t / m][t % m] = true;
    113         Q.push(t);
    114         bfs(dt);
    115         int ans = w[s] + w[t];
    116         for (int i = 0; i < door.size(); i++){
    117             ans = min(ans, ds[door[i]] + dt[door[i]] + w[door[i]] - 2);
    118         }
    119         printf("%d
    ", ans);
    120     }
    121 }
  • 相关阅读:
    详解ASP.NET MVC 2中强类型HTML辅助方法
    C#3.0规范(四)Lambda 表达式
    HTTP Status 检测器 : SEO在线工具 : SEO 网站优化推广
    CSS 命名规范
    数据库表及字段命名、设计规范
    C#变量命名中的[匈牙利命名法][骆驼命名法][帕斯卡(pascal)命名法]
    C#命名规范
    推荐磁盘分区管理工具Acronis Disk Director Suite 10.0(有效注册码+汉化补丁)
    经典海量jQuery插件
    GET PUT POST的含义(Http)
  • 原文地址:https://www.cnblogs.com/macinchang/p/4718108.html
Copyright © 2020-2023  润新知