#include #include #define MAX_V 10001 #define MAX_E 2000000 #define IS_MORE(a,b) ((a).value > (b).value) #define IS_BETTER(a,b) ((a) > (b)) #define SWAP(a,b) do{ int x = h[a].value; h[a].value = h[b].value; h[b].value = x; \ x = h[a].index_v; h[a].index_v = h[b].index_v; h[b].index_v = x; \ x = h[a].from_v; h[a].from_v = h[b].from_v; h[b].from_v = x; \ index_h[h[a].index_v] = a; index_h[h[b].index_v] = b; \ }while(0) #define MIN(a,b) ((a) < (b)? (a):(b)) struct heap_v{ int value; int index_v; int from_v; }; struct edge{ int to; int max_height; }; int v[MAX_V]; int visited_v[MAX_V]; struct edge e[MAX_E]; int index_h[MAX_V]; struct heap_v h[MAX_V]; int max_h = 0; void shif_down(int from); void shif_up(int from); void change(int index_h,int index_v, int new_value, int from_v); void add(int index_v, int value, int from_v); void delete(void); int N,M; int start,end; void read_input(void){ scanf(" %d",&N); scanf(" %d",&M); int** input = malloc(sizeof(int*)*M); for(int i = 0; i < M; i++){ input[i] = malloc(sizeof(int)*3); } int count_v[N+1]; for(int i = 0; i <= N; i++){ count_v[i] = 0; } for(int i = 0; i < M; i++){ int a,b,c; scanf(" %d", &a); scanf(" %d", &b); scanf(" %d", &c); count_v[a]++; count_v[b]++; input[i][0] = a; input[i][1] = b; input[i][2] = c; } v[0] = 0; v[1] = 0; for(int i = 2; i <= N; i++){ v[i] = v[i-1] + count_v[i-1]; } for(int i = 1; i <= N; i++){ count_v[i] = 0; } for(int i = 0; i < M; i++){ int a = input[i][0]; int b = input[i][1]; int index_a = count_v[a] + v[a]; int index_b = count_v[b] + v[b]; e[index_a].to = b; e[index_b].to = a; e[index_a].max_height = input[i][2]; e[index_b].max_height = input[i][2]; count_v[a]++; count_v[b]++; } scanf(" %d", &start); scanf(" %d", &end); for(int i = 0; i < M; i++){ free(input[i]); } free(input); } void solution(){ for(int i = v[start]; i < v[start+1]; i++){ change(index_h[e[i].to], e[i].to, e[i].max_height, start); } visited_v[start] = 1; int removed = 0; struct heap_v top = h[max_h+1]; do{ delete(); top = h[max_h+1]; SWAP(max_h+1,N-removed); // save top removed++; visited_v[top.index_v] = 1; for(int i = v[top.index_v]; i < v[top.index_v+1]; i++){ if(!visited_v[e[i].to]) change(index_h[e[i].to],e[i].to, MIN(e[i].max_height,top.value), top.index_v); } }while(top.index_v != end && max_h >= 1); } void write_backward(int from_v){ int a[MAX_V]; int index = 0; if(h[index_h[from_v]].from_v == 0){ printf("neexistuje cesta do cile"); return; } do{ a[index++] = from_v; from_v = h[index_h[from_v]].from_v; }while(from_v != start); printf("%d",start); for(int i = index - 1; i >= 0; i--){ printf(" %d",a[i]); } } void write_output(void){ printf("%d\n", h[index_h[end]].value); write_backward(end); printf("\n"); } int main(){ read_input(); solution(); write_output(); return 0; } void change(int index_h, int index_v, int new_value, int from_v){ if(index_h == 0) // it isnt in heap add(index_v, new_value, from_v); else{ if(IS_BETTER(new_value,h[index_h].value)){ h[index_h].value = new_value; h[index_h].from_v = from_v; shif_down(index_h); shif_up(index_h); } } } void delete(void){ SWAP(1, max_h); max_h--; shif_down(1); } void add(int index_v, int value, int from_v){ max_h++; h[max_h].index_v = index_v; h[max_h].value = value; h[max_h].from_v = from_v; index_h[index_v] = max_h; shif_up(max_h); } void shif_down(int root){ while (root*2 <= max_h){ int child = 2*root; if (child + 1 <= max_h && !IS_MORE(h[child], h[child+1]) ){ child = child+1; } if(IS_MORE(h[child], h[root])){ SWAP(child, root); root = child; }else{ break; } } } void shif_up(int i){ while ((i > 1) && IS_MORE(h[i], h[i/2])){ SWAP(i/2, i); i /= 2; } }