static void queue_push(struct node_info* queue, struct room_info* room, int cur_level, struct node_info* parent) { struct node_info* new_node = NULL; if (NULL == room) { return; } new_node = (struct node_info*)malloc(sizeof(struct node_info)); init_node_info(new_node); new_node->level = cur_level + 1; new_node->parent = parent; new_node->room = room; while (queue != NULL) { if (NULL == queue->next) { queue->next = new_node; break; } queue = queue->next; } }
void dijkstra(WEIGHT weight, int len, int src) { INFO_OF_NODE info; init_node_info(info, len, src); HEAP heap; int i; for(i = 0; i < len; ++i) heap[i] = i; build_min_heap(heap, info, len); int rear = len; while(rear > 0) { int q = heap[0]; info[q].color = BLACK; heap[0] = heap[--rear]; heap[rear] = q; keep_heap_property(heap, info, 0, rear); int i; for(i = 0; i < len; ++i) { //cause dijkstra can't support negative weight. if(weight[q][i] > 0 && info[i].color == WHITE) { relax_edge(q, i, heap, info, weight); } } } for(i = 0; i < len; ++i) { print_shortest_path(info, i, src); if(info[i].path_len == LONG_MAX) printf(" can't reach.\n"); else printf(" weight of path = %d\n", info[i].path_len); } }
/* 找到princess返回需要的步数 * 找不到或者出错返回-1 */ static int find_princess(struct room_info* maze, struct room_info* prince) { struct node_info* queue = NULL; struct node_info* cur_step = NULL; queue = (struct node_info*)malloc(sizeof(struct node_info)); if (NULL == queue) { return -1; } init_node_info(queue); queue->parent = NULL; queue->level = 0; queue->room = prince; cur_step = queue; while (cur_step != NULL) { struct room_info* cur_room = cur_step->room; if (NULL == cur_room) { fprintf(stderr, "IT CAN NOT HAPPEN!\n"); break; } if (TYPE_PRINCESS == cur_room->type) { struct node_info* tmp = cur_step; /* we find princess :) */ fprintf(stdout, "\nThe way back to prince... \n"); while (tmp != NULL) { fprintf(stdout, "(%d, %d) ", tmp->room->row, tmp->room->col); tmp = tmp->parent; } fprintf(stdout, "\n"); queue_release(queue); return cur_step->level; } else if (TYPE_ROAD == cur_room->type || TYPE_PRINCE == cur_room->type) { struct room_info* tmp = NULL; if (1 == cur_room->pass_by) { cur_step = cur_step->next; continue; } cur_room->pass_by = 1; /* 把孩子们丢到队列后面 */ tmp = cur_room->child[D_UP]; queue_push(queue, tmp, cur_step->level, cur_step); tmp = cur_room->child[D_DOWN]; queue_push(queue, tmp, cur_step->level, cur_step); tmp = cur_room->child[D_LEFT]; queue_push(queue, tmp, cur_step->level, cur_step); tmp = cur_room->child[D_RIGHT]; queue_push(queue, tmp, cur_step->level, cur_step); } else { fprintf(stderr, "Wired!\n"); } cur_step = cur_step->next; } queue_release(queue); return -1; }