luogu P1979 华容道

solution

被假hash可了半天....sadQAQ

code

// luogu-judger-enable-o2
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>

inline int read() {	
    int x = 0,f = 1;
    char c = getchar(); 
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();} 
    while(c <= '9' && c >= '0')x = x * 10 + c - '0' ,c = getchar();
    return x * f;
}
int n ,m,q;
const int maxn = 37; 
int fs1[5]={-1,1,0,0},fs2[5]={0,0,-1,1};
int dis[maxn][maxn]; 
int map[maxn][maxn];
struct Node {
    int x,y;
    Node (int X = 0,int Y = 0) : x(X),y(Y) {};
}; 
int head[maxn * 100000 + maxn * 1000 + maxn * 10 + maxn * 2];
int num = 0;
struct Edge { 
    int u ,v, w,next;
}edge[maxn * maxn << 1];
int base = 10;
int a[17],Num;
inline void fz(int x) { while(x) {a[++Num] = x % 10;x /= 10;} }
inline int hash(int x,int y,int type) {
    /*Num = 0;fz(type),fz(y),fz(x);
    int ret = a[Num];
    for(int i = Num - 1;i >= 1;-- i) ret = ret * base + a[i];*/ 
    return x * 120 + y * 4 + type; 
} 
inline void add_edge(int u,int v,int dis) { 
    edge[++num].v = v;edge[num].u = u;edge[num].w = dis,edge[num].next = head[u];head[u] = num; 
} 
void bfs(int Blax,int Blay,int x,int y,int type) { 
    std::queue<Node>que; 
    memset(dis,0,sizeof dis); 
    dis[Blax][Blay] = 1; 
    que.push(Node(Blax,Blay)); 
    while(!que.empty()) { 
        Node cur = que.front(); que.pop(); 
        for(int i = 0;i < 4;++ i) {
            int tx = cur.x + fs1[i],ty = cur.y + fs2[i]; 
            if(map[tx][ty] && ! dis[tx][ty] && (tx !=x || ty != y) ) {
                dis[tx][ty] = dis[cur.x][cur.y] + 1; 
                que.push(Node(tx,ty)); 		
            }
        } 	
    } 
    if(type == 11101001) return ; 
    for(int i = 0;i < 4;++ i) {
        int tx = x + fs1[i],ty = y + fs2[i]; 
        int a = hash(x,y,type),b = hash(x,y,i);
        if(dis[tx][ty] && (tx != Blax || ty != Blay)) add_edge(a,b , dis[tx][ty] - 1); 
    } 
    add_edge(hash(x,y,type),hash(Blax,Blay,type ^ 1),1); 
} 
int Dis[maxn * 100000 + maxn * 10000 + maxn * 10 + maxn * 2]; 
bool vis[maxn * 100000 + maxn * 10000 + maxn * 10 + maxn * 2];
void spfa(int x,int y) {
    memset(Dis,0x3f,sizeof Dis); 
    std::queue<int>que; 
    memset(vis,0,sizeof vis);
       	for(int tx,ty,i = 0;i < 4;++ i) {
        tx = x + fs1[i],ty = y + fs2[i]; 
        if(dis[tx][ty]) 
        Dis[hash(x,y,i)] = dis[tx][ty] - 1 ,vis[hash(x,y,i)] = 1 ,que.push(hash(x,y,i));
        //printf("%d %d %d %d\n",tx,ty,i,Dis[hash(tx,ty,i)]) ; 
        //printf("%d\n",dis[tx][ty]);
    }
    //printf("%d **********8\n",dis[hash(2,2,1)]) ;
    while(!que.empty()) {
        int u = que.front(); que.pop();
        for(int i = head[u];i;i = edge[i].next) {
            int v = edge[i].v;
            if(Dis[v] > Dis[u] + edge[i].w) {
                Dis[v] = Dis[u] + edge[i].w; if(!vis[v]) que.push(v),vis[v] = 1;
            } 
        } 
        vis[u] = 0; 
    } 
}
int main() {
    //printf("%d\n",hash(233,233,0));
    //printf("%d\n",0 % 10);
    n = read(),m = read(),q = read(); 
    for(int i = 1;i <= n;++ i)  
        for(int j = 1;j <= m;++ j) 
            map[i][j] = read(); 
    for(int i = 1;i <= n;++ i) 
        for(int j = 1;j <= m;++ j)  
            if(map[i][j]) { 
                if(map[i - 1][j]) bfs(i - 1,j,i,j,0); 
                   	if(map[i + 1][j]) bfs(i + 1,j,i,j,1); 
                if(map[i][j - 1]) bfs(i,j - 1,i,j,2); 
                if(map[i][j + 1]) bfs(i,j + 1,i,j,3); 	
            }  
    for(int a,b,c,d,e,f;q--;) { 
        a = read(),b = read(),c = read(),d = read(); e = read();f = read();
           	if(c == e && d == f){puts("0");continue;}	
        bfs(a,b,c,d,11101001); 
        spfa(c,d); int ans = 0x7fffffff; 
           	for(int i = 0;i < 4;++ i) ans = std::min(ans,Dis[hash(e,f,i)]);//,printf("%d ** %d ** %d ** \n",e,f,Dis[hash(e,f,i)]);   
        printf("%d\n",ans == 0x3f3f3f3f ? -1 : ans); 
    } 
    return 0;	
} 

posted @ 2018-05-02 22:03  zzzzx  阅读(175)  评论(0编辑  收藏  举报