Submission #47790
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | #include <stdio.h> #include <limits.h> #define max(X, Y) ((X) > (Y) ? (X) : (Y)) #define min(X, Y) ((X) < (Y) ? (X) : (Y)) //#include "vector.h" //#include "heap.h" #ifndef EI1710_VECTOR_H #define EI1710_VECTOR_H #include <stddef.h> #include <stdlib.h> #include <string.h> #include <stdio.h> typedef unsigned char Byte; //vector実現手法 //memcopy(), memmove()でオブジェクトをコピー //要素へのアクセスはsizeof(Type) * index バイト分先の要素を見て実現 //あらかじめ大き目に領域を取っておき、キャパシティオーバーしたらrealloc()する typedef struct { Byte *storage; //配列領域 size_t data_size; //格納データ型のサイズ size_t array_size; //格納データの個数 size_t capacity; //realloc()せずに格納できるデータ数 } Vector; //vectorの初期化 int Vector_init(Vector *vec, size_t data_size, size_t vec_size); //vector末尾にデータを追加 int Vector_push_back(Vector *vec, void *data); //vectorが管理するデータにアクセス void *Vector_array(Vector *vec, size_t i); //末尾のデータを削除 int Vector_pop_back(Vector *vec); //vectorをクリア void Vector_clear(Vector *vec); //vectorに格納しているデータの個数を返す size_t Vector_size(Vector *vec); //キャパシティを返す size_t Vector_capacity(Vector *vec); //vectorの初期化 int Vector_init(Vector *vec, size_t data_size, size_t vec_size) { vec->data_size = data_size; vec->capacity = 0; vec->array_size = 0; if (vec_size > 0) { vec->storage = calloc (vec_size, data_size); if (vec->storage == NULL) { return 0; } else { vec->capacity = vec_size; vec->array_size = vec_size; } } else { vec->storage = NULL; } return 1; } //vector末尾にデータを追加 int Vector_push_back(Vector *vec, void *data) { size_t indx = vec->array_size; size_t new_capacity = max(vec->capacity + 1, vec->capacity * 2); Byte *new_storage; //配列の再確保 if (indx >= vec->capacity) { new_storage = realloc (vec->storage, new_capacity * vec->data_size); if (new_storage == NULL) { return 0; } else { vec->storage = new_storage; vec->capacity = new_capacity; } } memcpy (vec->storage + (indx * vec->data_size), data, vec->data_size); vec->array_size = vec->array_size + 1; return 1; } //vectorが管理するデータにアクセス void *Vector_array(Vector *vec, size_t i) { if (i >= vec->array_size || i < 0) { return NULL; } else { return (vec->storage + (vec->data_size * i)); } } //vector末尾の要素を削除 int Vector_pop_back(Vector *vec) { if (vec->array_size == 0) { return 0; } else { vec->array_size--; } return 1; } //vectorをクリア void Vector_clear(Vector *vec) { free (vec->storage); Vector_init(vec, vec->data_size, 0); return ; } //vectorに格納しているデータの個数を返す size_t Vector_size(Vector *vec) { return vec->array_size; } //キャパシティを返す size_t Vector_capacity(Vector *vec) { return vec->capacity; } #endif #ifndef EI1710_HEAP_H //vectorを使って二分ヒープ typedef struct { Vector storage; int (*compare)( const void *, const void *); } Heap; //Heap構造体の初期化 void Heap_init(Heap *heap, size_t data_size, int (*compare)( const void *, const void *)); //Heapにデータを追加 int Heap_add(Heap *heap, void *); //Heapからデータを取り出す //取り出したデータは削除される int Heap_top(Heap *heap, void *); //Heapに格納されているデータ数を数える size_t Heap_size(Heap *heap); //Heapをクリア void Heap_clear(Heap *heap); #define parent_index(X) (((X) - 1) / 2) #define left_index(X) ((X) * 2 + 1) #define right_index(X) ((X) * 2 + 2) //Heapの根を削除 void Heap_remove(Heap *heap); void Heap_trickle_down(Heap *heap, int i); void Heap_bubble_up(Heap *heap, int i); //size Byteのメモリオブジェクトを入れ替え void memswap( void *x, void *y, size_t size); void Heap_init(Heap *heap, size_t data_size, int (*compare)( const void *, const void *)) { Vector_init(&(heap->storage), data_size, 0); heap->compare = compare; return ; } int Heap_top(Heap *heap, void *data) { if (Heap_size(heap) > 0) { if (data != NULL) { memcpy (data, Vector_array(&(heap->storage), 0), heap->storage.data_size); } Heap_remove(heap); return 1; } else { return 0; } } int Heap_add(Heap *heap, void *data) { if (Vector_push_back(&(heap->storage), data) == 0) { return 0; } Heap_bubble_up(heap, Vector_size(&(heap->storage)) - 1); return 1; } size_t Heap_size(Heap *heap) { return Vector_size(&(heap->storage)); } void Heap_clear(Heap *heap) { Vector_clear(&(heap->storage)); return ; } //----以下、.hに無い内部関数 void Heap_remove(Heap *heap) { memswap(Vector_array(&(heap->storage), 0), Vector_array(&(heap->storage), Vector_size(&(heap->storage)) - 1), heap->storage.data_size); Vector_pop_back(&(heap->storage)); Heap_trickle_down(heap, 0); return ; } void Heap_trickle_down(Heap *heap, int i) { do { int j = -1; int r = right_index(i); if (r < Vector_size(&(heap->storage)) && heap->compare(Vector_array(&(heap->storage), r), Vector_array(&(heap->storage), i)) < 0) { int l = left_index(i); if (heap->compare(Vector_array(&(heap->storage), l), Vector_array(&(heap->storage), r)) < 0) { j = l; } else { j = r; } } else { int l = left_index(i); if (l < Vector_size(&(heap->storage)) && heap->compare(Vector_array(&(heap->storage), l), Vector_array(&(heap->storage), i)) < 0) { j = l; } } if (j >= 0) { memswap(Vector_array(&(heap->storage), i), Vector_array(&(heap->storage), j), heap->storage.data_size); } i = j; } while (i >= 0); } void Heap_bubble_up(Heap *heap, int i) { int p = parent_index(i); while (i > 0 && heap->compare(Vector_array(&(heap->storage), i), Vector_array(&(heap->storage), p)) < 0) { memswap(Vector_array(&(heap->storage), i), Vector_array(&(heap->storage), p), heap->storage.data_size); i = p; p = parent_index(i); } return ; } //Xor Swap void memswap( void *x, void *y, size_t size) { if (x == y) { return ; } else { while (size--) { *((unsigned char *)x + size) ^= *((unsigned char *)y + size); *((unsigned char *)y + size) ^= *((unsigned char *)x + size); *((unsigned char *)x + size) ^= *((unsigned char *)y + size); } return ; } } #endif // INSERT ABOVE HERE //typedef long long ll; typedef struct { int to; int cost; } Edge; typedef struct { int pos; int cost; } State; const int inf = (INT_MAX / 2); Vector graph[100005]; int min_cost[100005]; int compare( const State *x, const State *y); void Dijkstra( void ); int main() { //init for ( int i = 0; i < 100005; i++) { Vector_init(&graph[i], sizeof (Edge), 0); min_cost[i] = inf; } int n, m; int x, y; int cost; //input scanf ( "%d %d" , &n, &m); for ( int i = 0; i < m; i++) { scanf ( "%d %d %d" , &x, &y, &cost); Vector_push_back(&graph[x], &(Edge){y, cost}); Vector_push_back(&graph[y], &(Edge){x, cost}); } Dijkstra(); if (min_cost[n] == inf) { puts ( "NA" ); } else { printf ( "%d\n" , min_cost[n]); } return 0; } void Dijkstra( void ) { Heap p_que; Heap_init(&p_que, sizeof (State), ( int (*)( const void *, const void *))compare); Heap_add(&p_que, &(State){.cost = 0, .pos = 1}); min_cost[1] = 0; while (Heap_size(&p_que) > 0) { State tmp; Heap_top(&p_que, &tmp); int pos = tmp.pos; int cost = tmp.cost; for ( int i = 0; i < Vector_size(&graph[pos]); i++) { int npos = ((Edge *)Vector_array(&graph[pos], i))->to; int ncost = cost + ((Edge *)Vector_array(&graph[pos], i))->cost; if (min_cost[npos] > ncost) { min_cost[npos] = ncost; Heap_add(&p_que, &(State){.pos = npos, .cost = ncost}); } } } return ; } int compare( const State *x, const State *y) { if (x->cost > y->cost) { return 1; } else if (x->cost == y->cost) { return 0; } else { return -1; } } |
ステータス
項目 | データ |
---|---|
問題 | 0431 - 君も始めようダイクストラ大好き厨 |
ユーザー名 | ei1710 |
投稿日時 | 2019-03-27 16:56:32 |
言語 | C(gnu99) |
状態 | Accepted |
得点 | 1 |
ソースコード長 | 8482 Byte |
最大実行時間 | 79 ms |
最大メモリ使用量 | 7640 KB |
セット
セット | 得点 | Cases | |
---|---|---|---|
1 | ALL | 1 / 1 | * |
テストケース
ファイル名 | 状態 | 実行時間 | メモリ使用量 | # |
---|---|---|---|---|
m_in1.txt | AC | 79 ms | 7640 KB |
1
|
r_in1.txt | AC | 39 ms | 4856 KB |
1
|
r_in2.txt | AC | 34 ms | 4944 KB |
1
|
r_in3.txt | AC | 32 ms | 4864 KB |
1
|
r_in4.txt | AC | 29 ms | 4416 KB |
1
|
r_in5.txt | AC | 31 ms | 5024 KB |
1
|
r_in6.txt | AC | 33 ms | 4968 KB |
1
|
r_in7.txt | AC | 24 ms | 4464 KB |
1
|
r_in8.txt | AC | 24 ms | 4472 KB |
1
|
r_in9.txt | AC | 35 ms | 5060 KB |
1
|
r_in10.txt | AC | 33 ms | 4436 KB |
1
|
r_in11.txt | AC | 26 ms | 4648 KB |
1
|
r_in12.txt | AC | 40 ms | 4692 KB |
1
|
r_in13.txt | AC | 44 ms | 4824 KB |
1
|
r_in14.txt | AC | 41 ms | 4892 KB |
1
|
r_in15.txt | AC | 35 ms | 4932 KB |
1
|
r_in16.txt | AC | 29 ms | 4548 KB |
1
|
r_in17.txt | AC | 35 ms | 4640 KB |
1
|
r_in18.txt | AC | 27 ms | 4680 KB |
1
|
r_in19.txt | AC | 28 ms | 4416 KB |
1
|
r_in20.txt | AC | 27 ms | 4604 KB |
1
|
r_in21.txt | AC | 25 ms | 4232 KB |
1
|
r_in22.txt | AC | 23 ms | 4388 KB |
1
|
r_in23.txt | AC | 23 ms | 4468 KB |
1
|
r_in24.txt | AC | 24 ms | 4368 KB |
1
|
r_in25.txt | AC | 23 ms | 4476 KB |
1
|
r_in26.txt | AC | 28 ms | 4504 KB |
1
|
r_in27.txt | AC | 33 ms | 4588 KB |
1
|
r_in28.txt | AC | 34 ms | 4648 KB |
1
|
r_in29.txt | AC | 32 ms | 4656 KB |
1
|
r_in30.txt | AC | 29 ms | 4752 KB |
1
|