• UVa1601


    ---恢复内容开始---

    这道题的题解很多,所以就不用说明了。

    下面便是单dfs与双dfs的代码 

     900ms

    // UVa 1601
    // bfs(原始) 
    #include <cstdio>
    #include <cstring>
    #include <cctype> 
    #include <queue> 
    using namespace std; 
    const int maxc = 20; 
    const int maxn = 256; 
    
    const int dx[] = {-1, 1, 0, 0, 0};
    const int dy[] = {0, 0, -1, 1, 0};
    
    int w, h, n; 
    int s[3], t[3];
    int deg[maxn], G[maxn][5]; 
    
    int get_ID(int a, int b, int c) {
      return (a<<16)|(b<<8)|c; 
    }
    
    bool is_conflict(int a, int b, int a1, int b1) {
      return (a1 == b1) || (a == b1 && b == a1);     
    }
    
    int dist[maxn][maxn][maxn]; 
    
    int bfs() {
      queue<int> q;
      memset(dist, -1, sizeof(dist));   
      q.push(get_ID(s[0], s[1], s[2])); 
      dist[s[0]][s[1]][s[2]] = 0;
      while (!q.empty()) {
        int u = q.front(); q.pop();
        int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff; 
        if (a == t[0] && b == t[1] && c == t[2]) return dist[a][b][c]; 
        for (int i = 0; i < deg[a]; ++i) {
          int a1 = G[a][i]; 
          for (int j = 0; j < deg[b]; ++j) {
            int b1 = G[b][j]; 
            if (is_conflict(a, b, a1, b1)) continue; 
            for (int k = 0; k < deg[c]; ++k) {
              int c1 = G[c][k];
              if (is_conflict(a, c, a1, c1)) continue; 
              if (is_conflict(b, c, b1, c1)) continue; 
              if (dist[a1][b1][c1] != -1) continue;  
              dist[a1][b1][c1] = dist[a][b][c] + 1;
              q.push(get_ID(a1, b1, c1));  
            }
          } 
        }
      }
      return -1; 
    }
    
    int main() {
      while (scanf("%d%d%d
    ", &w, &h, &n) == 3 && n) {
        int cnt = 0, x[maxn], y[maxn], id[maxc][maxc];
        char input[maxc][maxc]; 
        for (int i = 0; i < h; ++i)
          fgets(input[i], maxc, stdin); 
        for (int i = 0; i < h; ++i) 
          for (int j = 0; j < w; ++j) 
            if (input[i][j] != '#') {
              x[cnt] = i; y[cnt] = j; id[i][j] = cnt; 
              if (islower(input[i][j])) s[input[i][j]-'a'] = cnt; 
              else if (isupper(input[i][j])) t[input[i][j]-'A'] = cnt; 
              cnt++; 
            }
        for (int i = 0; i < cnt; ++i) {
          deg[i] = 0;
          for (int j = 0; j < 5; ++j) {
            int x1 = x[i]+dx[j], y1 = y[i]+dy[j];
            if (input[x1][y1] != '#') G[i][deg[i]++] = id[x1][y1];
          }
        }
        if (n <= 2) { deg[cnt] = 1; G[cnt][0] = cnt; s[2] = t[2] = cnt++; }
        if (n <= 1) { deg[cnt] = 1; G[cnt][0] = cnt; s[1] = t[1] = cnt++; } 
        printf("%d
    ", bfs()); 
      }
      return 0;
    }

    750ms

    // UVa 1601 
    // 双向bfs
    #include <cstdio>
    #include <cstring> 
    #include <cctype> 
    #include <queue> 
    using namespace std; 
    const int maxc = 20; 
    const int maxn = 256; 
    
    const int dx[] = {1, -1, 0, 0, 0}; 
    const int dy[] = {0, 0, 1, -1, 0}; 
    
    int w, h, n;
    int deg[maxn], G[maxn][5]; 
    
    int s[3], t[3]; 
    
    int ID(int a, int b, int c) { return (a<<16)|(b<<8)|c; }
    
    bool is_conflict(int a, int b, int a1, int b1) {
      return (a1 == b1) || (a == b1 && b == a1);    
    }
    
    int ds[maxn][maxn][maxn];
    int dt[maxn][maxn][maxn];  
    
    int dfs() {
      queue<int> qs, qt; 
      qs.push(ID(s[0], s[1], s[2])); 
      qt.push(ID(t[0], t[1], t[2])); 
      memset(ds, -1, sizeof(ds));
      memset(dt, -1, sizeof(dt));
      ds[s[0]][s[1]][s[2]] = dt[t[0]][t[1]][t[2]] = 0;
      while (!qs.empty() && !qt.empty()) {
        {
          int u = qs.front(); qs.pop(); 
          int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff;
          for (int i = 0; i < deg[a]; ++i) {
            int a1 = G[a][i]; 
            for (int j = 0; j < deg[b]; ++j) {
              int b1 = G[b][j]; 
              if (is_conflict(a, b, a1, b1)) continue;  
              for (int k = 0; k < deg[c]; ++k) {
                int c1 = G[c][k];
                if (is_conflict(a, c, a1, c1)) continue; 
                if (is_conflict(b, c, b1, c1)) continue;
                if (ds[a1][b1][c1] == -1) { ds[a1][b1][c1] = ds[a][b][c] + 1; qs.push(ID(a1, b1, c1)); } 
                if (dt[a1][b1][c1] != -1) return ds[a1][b1][c1] + dt[a1][b1][c1];      
              }
            }
          }
        }
        {
          int u = qt.front(); qt.pop(); 
          int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff;
          for (int i = 0; i < deg[a]; ++i) {
            int a1 = G[a][i]; 
            for (int j = 0; j < deg[b]; ++j) {
              int b1 = G[b][j]; 
              if (is_conflict(a, b, a1, b1)) continue;  
              for (int k = 0; k < deg[c]; ++k) {
                int c1 = G[c][k];
                if (is_conflict(a, c, a1, c1)) continue; 
                if (is_conflict(b, c, b1, c1)) continue;
                if (dt[a1][b1][c1] == -1) { dt[a1][b1][c1] = dt[a][b][c] + 1; qt.push(ID(a1, b1, c1)); }
                if (ds[a1][b1][c1] != -1) return dt[a1][b1][c1] + ds[a1][b1][c1];      
              }
            }
          }
        }
      }
      return -1; 
    } 
    
    int main() { 
      while (scanf("%d%d%d
    ", &w, &h, &n) == 3 && n) {    
        char input[maxc][maxc]; 
        int cnt = 0, x[maxn], y[maxn], id[maxc][maxc]; 
        for (int i = 0; i < h; ++i) 
          fgets(input[i], maxc, stdin);  
        for (int i = 0; i < h; ++i) 
          for (int j = 0; j < w; ++j) if (input[i][j] != '#') {
            x[cnt] = i; y[cnt] = j; id[i][j] = cnt; 
            if (islower(input[i][j])) s[input[i][j]-'a'] = cnt; 
            else if (isupper(input[i][j])) t[input[i][j]-'A'] = cnt; 
            cnt++; 
          }
        for (int i = 0; i < cnt; ++i) {
          deg[i] = 0; 
          for (int j = 0; j < 5; ++j) {
            int x1 = x[i]+dx[j], y1 = y[i]+dy[j];
            if (input[x1][y1] != '#') { G[i][deg[i]++] = id[x1][y1]; }     
          }
        }
        if (n <= 2) { deg[cnt] = 1; G[cnt][0] = cnt; s[2] = t[2] = cnt++; } 
        if (n <= 1) { deg[cnt] = 1; G[cnt][0] = cnt; s[1] = t[1] = cnt++; }
        printf("%d
    ", dfs()); 
      }
      return 0;
    }

    单dfs的查询节点大概是 n ^ len

    双dfs的查询节点大概是 2 * n ^ (len / 2) 

    n, len越大优化程度越高

  • 相关阅读:
    哲学的初步认识7
    随机法解决TSP问题
    哲学的初步认识6
    dfs+dp思想的结合------hdu1078
    动态规划3-------poj1050
    动态规划2-----hdu1069
    动态规划1-----------poj1080
    js中Math.round、parseInt、Math.floor和Math.ceil小数取整小结【转】
    美术馆
    无刷新评论
  • 原文地址:https://www.cnblogs.com/yifeiWa/p/11019233.html
Copyright © 2020-2023  润新知