#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <math.h>
#include <string.h>
#define INF 100000000
typedef int keyType;
typedef struct node{
keyType key;
struct node *parent, *left, *right;
}node;
typedef struct heap{
unsigned int count;
struct node *root_node, *last_node;
}heap;
typedef struct edge{
int head_vertex, cost;
struct edge *next;
} edge;
typedef struct vertex{
node heap_node;
int predecessor, key;
edge *adjacent;
} vertex;
void free_graph(vertex *vertices, int size);
void init_graph(vertex *vertices, int size, int source);
void insert_edge(vertex *vertices, int tail, int head, int cost);
heap* heap_create(void);
node* heap_create_node(keyType key);
node* heap_insert_child(heap *root);
void heap_decrease_key(heap *root, node *heap_node, keyType key);
void heap_insert(heap *root, node *heap_node);
void heap_swap_left(heap *root, node *heap_node);
void heap_swap_right(heap *root, node *heap_node);
void heap_increase_key(heap *root, node *heap_node, keyType key);
node* heap_find_last(heap *root);
node* heap_get_min(heap *root);
heap* heap_create(void){
heap
*new_heap
= (heap
*)malloc(sizeof(heap
)); new_heap->count = 0;
new_heap->root_node = new_heap->last_node = NULL;
return new_heap;
}
node* heap_create_node(keyType key){
node
*new_node
= (node
*)malloc(sizeof(node
)); new_node->key = key;
new_node->parent = new_node->left = new_node->right = NULL;
return new_node;
}
node* heap_insert_child(heap *root){
node *aux = root->last_node;
unsigned int N = root->count+1;
if (fabs((int)(log2
(N
)) - log2
(N
))<1e-8){ aux = root->root_node;
while (aux->left) {
aux = aux->left;
}
}
else if ( N % 2 == 0){
while(aux->parent->right == aux)
aux = aux->parent;
if(!aux->parent->right)
return aux->parent;
aux = aux->parent->right;
while(aux->left)
aux = aux->left;
}
else{
aux = aux->parent;
}
return aux;
}
void heap_decrease_key(heap *root, node *heap_node, keyType key){
heap_node->key = key;
node *parent = heap_node->parent;
node *left = heap_node->left;
node *right = heap_node->right;
if(!parent)
return;
if(parent->key > heap_node->key){
if(root->last_node == heap_node)
root->last_node = parent;
}
while(parent && (parent->key > heap_node->key)){
if(parent->left == heap_node){
heap_node->left = parent;
heap_node->right = parent->right;
if(heap_node->right)
heap_node->right->parent = heap_node;
heap_node->parent = parent->parent;
if(heap_node->parent){
if(heap_node->parent->left == parent)
heap_node->parent->left = heap_node;
else
heap_node->parent->right = heap_node;
}
else
root->root_node = heap_node;
}
else{
heap_node->right = parent;
heap_node->left = parent->left;
if(heap_node->left)
heap_node->left->parent = heap_node;
heap_node->parent = parent->parent;
if(heap_node->parent){
if(heap_node->parent->left == parent)
heap_node->parent->left = heap_node;
else
heap_node->parent->right = heap_node;
}
else
root->root_node = heap_node;
}
parent->left = left;
parent->right = right;
parent->parent = heap_node;
if(left)
left->parent = parent;
if(right)
right->parent = parent;
parent = heap_node->parent;
left = heap_node->left;
right = heap_node->right;
}
}
void heap_insert(heap *root, node *heap_node){
node *parent = NULL;
heap_node->parent = heap_node->left = heap_node->right = NULL;
if(!root->count){
root->root_node = root->last_node = heap_node;
root->count++;
}
else{
parent = heap_insert_child(root);
if(parent->left){
parent->right = heap_node;
}
else{
parent->left = heap_node;
}
heap_node->parent = parent;
root->count++;
root->last_node = heap_node;
heap_decrease_key(root, heap_node, heap_node->key);
}
}
void heap_swap_left(heap *root, node *heap_node){
node *parent = heap_node->parent;
node *left = heap_node->left;
node *right = heap_node->right;
heap_node->parent = left;
heap_node->left = left->left;
if(heap_node->left)
heap_node->left->parent = heap_node;
heap_node->right = left->right;
if(heap_node->right)
heap_node->right->parent = heap_node;
left->parent = parent;
if(parent){
if(parent->left == heap_node)
parent->left = left;
else
parent->right = left;
}
else
root->root_node = left;
left->left = heap_node;
left->right = right;
if(right)
right->parent = left;
if(root->last_node == left)
root->last_node = heap_node;
}
void heap_swap_right(heap *root, node *heap_node){
node *parent = heap_node->parent;
node *left = heap_node->left;
node *right = heap_node->right;
heap_node->parent = right;
heap_node->left = right->left;
if(heap_node->left)
heap_node->left->parent = heap_node;
heap_node->right = right->right;
if(heap_node->right)
heap_node->right->parent = heap_node;
right->parent = parent;
if(parent){
if(parent->left == heap_node)
parent->left = right;
else
parent->right = right;
}
else
root->root_node = right;
right->right = heap_node;
right->left = left;
if(left)
left->parent = right;
if(root->last_node == right)
root->last_node = heap_node;
}
void heap_increase_key(heap *root, node *heap_node, keyType key){
heap_node->key = key;
node *left = heap_node->left;
node *right = heap_node->right;
if(left && (heap_node->key > left->key)){
if(right && (heap_node->key > right->key)){
if(left->key < right->key)
heap_swap_left(root, heap_node);
else
heap_swap_right(root, heap_node);
}
else
heap_swap_left(root, heap_node);
heap_increase_key(root, heap_node, key);
}
else if(right && (heap_node->key > right->key)){
heap_swap_right(root, heap_node);
heap_increase_key(root, heap_node, key);
}
}
node* heap_find_last(heap *root){
node *aux = root->last_node;
unsigned int N = root->count+1;
if (fabs((int)(log2
(N
)) - log2
(N
))<1e-8){ aux = root->root_node;
while (aux->right) {
aux = aux->right;
}
}
else if ( N % 2 == 0){
while(aux->parent->left == aux)
aux = aux->parent;
aux = aux->parent->left;
while(aux->right)
aux = aux->right;
}
return aux;
}
node *heap_get_min(heap *root){
node *min_node = root->root_node;
node *new_min = root->last_node;
if(!min_node)
return NULL;
root->count--;
if(root->count == 0){
root->last_node = root->root_node = NULL;
return min_node;
}
if(root->count == 1){
root->last_node = root->root_node = new_min;
new_min->parent = NULL;
return min_node;
}
else{
if(new_min->parent->left == new_min){
new_min->parent->left = NULL;
root->last_node = new_min->parent;
root->last_node = heap_find_last(root);
}
else{
new_min->parent->right = NULL;
root->last_node = new_min->parent->left;
}
new_min->left = min_node->left;
if(new_min->left)
new_min->left->parent = new_min;
new_min->right = min_node->right;
if (new_min->right)
new_min->right->parent = new_min;
new_min->parent = NULL;
root->root_node = new_min;
heap_increase_key(root, new_min, new_min->key);
}
return min_node;
}
void init_graph(vertex *vertices, int size, int source){
int i;
for(i=0; i<size; i++) {
vertices[i].predecessor = -1;
vertices[i].adjacent = NULL;
vertices[i].key = i;
vertices[i].heap_node.key = INF;
vertices[i].heap_node.parent = NULL;
vertices[i].heap_node.left = NULL;
vertices[i].heap_node.right = NULL;
}
vertices[source].heap_node.key = 0;
}
void insert_edge(vertex *vertices, int tail, int head, int cost){
edge
*new_edge
= (edge
*)malloc(sizeof(edge
)); new_edge->next = vertices[tail].adjacent;
new_edge->head_vertex = head;
new_edge->cost = cost;
vertices[tail].adjacent = new_edge;
}
void free_graph(vertex *vertices, int size){
int i;
edge *aux, *aux2;
if(!vertices)
return;
for(i=0; i<size; i++){
aux = vertices[i].adjacent;
while(aux){
aux2 = aux->next;
aux = aux2;
}
}
}
void dijkstra(vertex *vertices, heap *root){
int new_cost, adjacent;
node *min_node;
vertex *min_vertex, *adjacent_vertex;
while(root->root_node){
min_node = heap_get_min(root);
min_vertex = (vertex*)min_node;
edge *aux = min_vertex->adjacent;
while(aux){
adjacent = aux->head_vertex;
new_cost = min_vertex->heap_node.key + aux->cost;
adjacent_vertex = &(vertices[adjacent]);
if(new_cost < adjacent_vertex->heap_node.key){
if(adjacent_vertex->heap_node.key == INF){
adjacent_vertex->heap_node.key = new_cost;
heap_insert(root, &(adjacent_vertex->heap_node));
}
else{
heap_decrease_key(root, &(adjacent_vertex->heap_node), new_cost);
}
adjacent_vertex->predecessor = min_vertex->key;
adjacent_vertex->heap_node.key = new_cost;
}
aux = aux->next;
}
}
}
int main(void){
int n, m, n0, m0, n1, m1;
scanf("%d%d%d%d%d%d", &n
, &m
, &n0
, &m0
, &n1
, &m1
); short map[n][m];
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
}
}
int to=n1+m1*n;
int from=n0+m0*n;
if(n1==n0&&m1==m0){
return 0;
}
heap *root = heap_create();
vertex
*v
=malloc(n
*m
*sizeof(vertex
)); init_graph(v,m*n,from);
heap_insert(root, &(v[from].heap_node));
for(int i=0;i<n;i++){
for(int j=0; j<m; j++){
if(i>0){
int diff
=abs(map
[i
][j
]-map
[i
-1][j
]); insert_edge(v,i+n*j,i-1+n*j,diff);
}
if(i<n-1){
int diff
=abs(map
[i
][j
]-map
[i
+1][j
]); insert_edge(v,i+n*j,i+1+n*j,diff);
}
if(j>0){
int diff
=abs(map
[i
][j
]-map
[i
][j
-1]); insert_edge(v,i+n*j,i+n*(j-1),diff);
}
if(j<m-1){
int diff
=abs(map
[i
][j
]-map
[i
][j
+1]); insert_edge(v,i+n*j,i+n*(j+1),diff);
}
}
}
dijkstra(v,root);
printf("%d",v
[to
].
heap_node.
key);
free_graph(v, n*m);
return 0;
}