⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poj3523_双向bfs.cpp

📁 本人最近在acm.pku.edu.cn上通过的程序
💻 CPP
字号:
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std ;

const int MaxR = 20 ;
const int MaxN = 255 ;
const int MaxQ = 800000;
const int dx[5] = {-1 , 0 , 1 , 0 , 0} ;
const int dy[5] = {0 , 1 , 0 , -1 , 0} ;

int tot , w , h , n ;
char Map[MaxR][MaxR] ;
int ord[MaxR][MaxR] ;
int e[MaxN][6], len[MaxN];
int d1[MaxQ] ,d2[MaxQ], q1[MaxQ], q2[MaxQ], cur1 , tail1, cur2, tail2 ;
int goal, start ;
bool found ;
int sd ;

unsigned char hash[256*256*256+3];
unsigned char hash2[256*256*256+3];

bool init() {
  if (3!=scanf("%d%d%d" , &h , &w , &n) || w+h+n==0) return false ;
  gets(Map[0]) ;
  for (int i = 0 ; i<w ; ++i) gets(Map[i]) ;

  tot = 0 ;
  for (int i = 0 ; i<w ; ++i)
    for (int j = 0 ; j<h ; ++j) if (Map[i][j]!='#') ord[i][j] = tot++ ;

  memset(len , 0 , sizeof(len)) ;
  for (int i = 0 ; i<w ; ++i)
    for (int j = 0 ; j<h ; ++j) if (Map[i][j]!='#') {
      int c = ord[i][j] ;
      for (int k = 0 ; k<5 ; ++k) {
	int tx = i+dx[k] , ty = j+dy[k] ;
	if (Map[tx][ty]!='#') e[c][len[c]++] = ord[tx][ty] ;
      }
    }

  goal = 0 ;  start = 0;
  for (int i = 0 ; i<w ; ++i)
    for (int j = 0 ; j<h ; ++j) {
      if (islower(Map[i][j])) start |= (ord[i][j]<<8*(Map[i][j]-'a')) ;
      if (isupper(Map[i][j])) goal |= (ord[i][j]<<8*(Map[i][j]-'A')) ;
    }
    
  return true ;
}

inline void encode(int&s , int*a) {
  static int i ;
  s = 0 ;
  for (i = n-1 ; i>=0 ; --i) s = (s<<8)+a[i] ;
}

inline void decode(int s , int*a) {
  static int i ;
  for (i = 0 ; i<n ; ++i) a[i] = s&255 , s>>=8 ;
}

void expand(int*a , int*b , int dep) {
    if (found) return;
  if (dep==n) {
    for (int i = 0 ; i<n ; ++i)
      for (int j = i+1 ; j<n ; ++j) {
	if (b[i]==b[j]) return ;
	if (a[i]==b[j]&&a[j]==b[i]) return ;
      }

    int s ;
    encode(s , b);

    if (hash[s] == 0xff) {
      hash[s] = sd + 1 ;  q1[tail1] = s ; d1[tail1++] = sd+1 ;if (tail1 >= MaxQ) tail1 = 0;
      if (s==goal) { found = true ; printf("%d\n" , sd+1) ; return ; }
    }
    if (hash2[s] != 0xff){
        printf("%d\n", hash2[s] + sd + 1); found = true; return;
    }
    return ;
  }

  for (int i = len[a[dep]]-1 ; i>=0 ; --i) {
    b[dep] = e[a[dep]][i] ;
    expand(a , b , dep+1) ;
  }
}


void expand2(int*a , int*b , int dep) {
    if (found) return ;
  if (dep==n) {
    for (int i = 0 ; i<n ; ++i)
      for (int j = i+1 ; j<n ; ++j) {
	if (b[i]==b[j]) return ;
	if (a[i]==b[j]&&a[j]==b[i]) return ;
      }

    int s ;
    encode(s , b) ;

    if (hash2[s] == 0xff) {
      hash2[s] = sd + 1 ; q2[tail2] = s ; d2[tail2++] = sd+1 ;if (tail2 >= MaxQ) tail2 = 0;
      if (s==start) { found = true ; printf("%d\n" , sd+1) ; return ; }
    }
    if (hash[s] != 0xff){
        printf("%d\n", hash[s] + sd + 1); found = true; return;
    }
    return ;
  }

  for (int i = len[a[dep]]-1 ; i>=0 ; --i) {
    b[dep] = e[a[dep]][i] ;
    expand2(a , b , dep+1) ;
  }
}

void solve() {
  int a[3] , b[3] ;
  memset(hash , 0xff , sizeof(hash)) ; 
  q1[0] = start;
  hash[q1[0]] = 0 ; 
  d1[0] = 0 ; found = false ;
  memset(hash2, 0xff, sizeof(hash2));
  d2[0] = 0; q2[0] = goal; hash2[q2[0]] = 1;
  int k = 0;
  cur1 = 0, cur2 = 0;
  tail1 = 1, tail2 = 1; 
  while (1){
    k++;
    for (; cur1<tail1 ; ++cur1) {
        if (cur1 >= MaxQ) tail2 = 0;
        decode(q1[cur1] , a) ; sd = d1[cur1] ;
        if (sd > k) break;
        expand(a , b , 0) ;
        if (found) return ;
    }
    for (; cur2 < tail2; ++cur2){
        if (cur2 >= MaxQ) tail2 = 0;
        decode(q2[cur2], a); sd = d2[cur2];
        if (sd > k) break;
        expand2(a, b, 0);
        if (found) return ;
    }
  }
}

int main() {
    //freopen("G.in", "r", stdin);
  while (init()) 
    solve() ;
    //system("pause");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -