#include <stdio.h>
#include <malloc.h>
#include <limits.h>
typedef unsigned short word_t;
typedef unsigned char byte_t;
typedef struct node {
struct node* next;
word_t v;
} node_t;
typedef struct {
node_t* h, *t;
} queue_t;
void queue_init(queue_t* q){ q->h = q->t = NULL; }
int queue_empty(queue_t* q){ return (q->h == NULL); }
word_t queue_front(queue_t* q) { return q->h->v; }
int queue_push(queue_t* q, word_t v);
void queue_pop(queue_t* q);
void queue_clear(queue_t* q);
typedef struct {
word_t v, p;
} vert_t;
byte_t** graph_input(FILE* _in, int* n);
void graph_free(byte_t** g, int n);
word_t* graph_bfs(byte_t** g, int n, word_t s, word_t e, int* m);
int main(void){
int i, n, m;
word_t* p, s, e;
byte_t** g;
/* ввод из файла
FILE* f = fopen("graph.txt", "rt");
if(f == NULL)
return 1;
g = graph_input(f, &n);
fclose(f);
*/
g = graph_input(stdin, &n);
if(g == NULL)
return 1;
s = 3;//старт
e = 4;//конец
p = graph_bfs(g, n, s, e, &m);
if(p != NULL){
printf("path: ");
for(i = 0; i < m; ++i)
printf("%u ", p[i]);
putchar('\n');
free(p);
} else
fputs("error find bfs!\n", stderr);
graph_free(g, n);
return 0;
}
//поиск в ширину
word_t* graph_bfs(byte_t** g, int n, word_t s, word_t e, int* m){
int i, y;
queue_t q;
vert_t* vs;
word_t v, *p, *d, *j;
p = NULL;
vs = (vert_t*)malloc((size_t)n * sizeof(vert_t));
if(vs == NULL)
return NULL;
for(i = 0; i < n; ++i)
vs[i].p = vs[i].v = USHRT_MAX;
vs[s].v = 0;
queue_init(&q);
queue_push(&q, s);
y = 0;
while(! queue_empty(&q)){
v = queue_front(&q);
queue_pop(&q);
if(v == e){
y = 1;
break;
}
for(i = 0; i < n; ++i){
if((g[v][i] != 0) && (vs[i].v > (vs[v].v + 1))){
queue_push(&q, (word_t)i);
vs[i].p = v;
vs[i].v = vs[v].v + 1;
}
}
}
queue_clear(&q);
if(y){
v = e;
i = 1;
while(v != s){
v = vs[v].p;
++i;
}
p = (word_t*)malloc((size_t)i * sizeof(word_t));
if(p == NULL)
return NULL;
d = p;
for(*d++ = e; e != s; e = vs[e].p)
*d++ = vs[e].p;
for(--d, j = p; j < d; ++j, --d){
v = *d;
*d = *j;
*j = v;
}
*m = i;
}
free(vs);
return p;
}
/*
ввод неориентированного графа, формат
N - кол-во вершин M - кол-во рёбер
*/
byte_t** graph_input(FILE* _in, int* n){
int i, j, vn, em, a, b;
byte_t** g;
if((fscanf(_in, "%d %d", &vn, &em) != 2) || (vn <= 1) || (em <= 1))
return NULL;
g = (byte_t**)malloc((size_t)vn * sizeof(byte_t*));
if(g == NULL)
return NULL;
for(i = 0; i < vn; ++i){
g[i] = (byte_t*)calloc((size_t)vn, sizeof(byte_t));
if(g[i] == NULL){
i -= 1;
goto err;
}
}
for(i = 0; i < em; ++i){
if(fscanf(_in, "%d %d", &a, &b) == 2){
if((a < vn) && (b < vn))
g[a][b] = g[b][a] = 1;
} else
break;
}
*n = vn;
return g;
err:
for(j = i; j >= 0; --j)
free(g[j]);
free(g);
return NULL;
}
//удаление графа из памяти
void graph_free(byte_t** g, int n){
int i;
for(i = 0; i < n; ++i)
free(g[i]);
free(g);
}
//---------------
//вставка
int queue_push(queue_t* q, word_t v){
node_t* p = (node_t*)malloc(sizeof(node_t));
if(p != NULL){
p->v = v;
p->next = NULL;
if(q->h == NULL)
q->h = q->t = p;
else {
q->t->next = p;
q->t = p;
}
}
return (p != NULL);
}
//извлечение
void queue_pop(queue_t* q){
node_t* t;
if(q->h != NULL){
t = q->h;
q->h = q->h->next;
free(t);
if(q->h == NULL)
q->t = NULL;
}
}
//удаление всех
void queue_clear(queue_t* q){
while(! queue_empty(q))
queue_pop(q);
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYWxsb2MuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgp0eXBlZGVmIHVuc2lnbmVkIHNob3J0IHdvcmRfdDsKdHlwZWRlZiB1bnNpZ25lZCBjaGFyICBieXRlX3Q7Cgp0eXBlZGVmIHN0cnVjdCBub2RlIHsKCXN0cnVjdCBub2RlKiBuZXh0OwoJd29yZF90IHY7Cn0gbm9kZV90OwoKdHlwZWRlZiBzdHJ1Y3QgewoJbm9kZV90KiBoLCAqdDsKfSBxdWV1ZV90OwoKdm9pZCAgIHF1ZXVlX2luaXQocXVldWVfdCogcSl7IHEtPmggPSBxLT50ID0gTlVMTDsgfQppbnQgICAgcXVldWVfZW1wdHkocXVldWVfdCogcSl7IHJldHVybiAocS0+aCA9PSBOVUxMKTsgfQp3b3JkX3QgcXVldWVfZnJvbnQocXVldWVfdCogcSkgeyByZXR1cm4gcS0+aC0+djsgfQppbnQgICAgcXVldWVfcHVzaChxdWV1ZV90KiBxLCB3b3JkX3Qgdik7CnZvaWQgICBxdWV1ZV9wb3AocXVldWVfdCogcSk7CnZvaWQgICBxdWV1ZV9jbGVhcihxdWV1ZV90KiBxKTsKCnR5cGVkZWYgc3RydWN0IHsKCXdvcmRfdCB2LCBwOwp9IHZlcnRfdDsKYnl0ZV90KiogZ3JhcGhfaW5wdXQoRklMRSogX2luLCBpbnQqIG4pOwp2b2lkICAgICBncmFwaF9mcmVlKGJ5dGVfdCoqIGcsIGludCBuKTsKd29yZF90KiAgZ3JhcGhfYmZzKGJ5dGVfdCoqIGcsIGludCBuLCB3b3JkX3Qgcywgd29yZF90IGUsIGludCogbSk7CgoKaW50IG1haW4odm9pZCl7CglpbnQgICAgICBpLCBuLCBtOwoJd29yZF90KiAgcCwgcywgZTsKCWJ5dGVfdCoqIGc7CgovKiAgINCy0LLQvtC0INC40Lcg0YTQsNC50LvQsAoJRklMRSogZiA9IGZvcGVuKCJncmFwaC50eHQiLCAicnQiKTsKCWlmKGYgPT0gTlVMTCkKCQlyZXR1cm4gMTsKCWcgPSBncmFwaF9pbnB1dChmLCAmbik7CglmY2xvc2UoZik7CiovCglnID0gZ3JhcGhfaW5wdXQoc3RkaW4sICZuKTsKCWlmKGcgPT0gTlVMTCkKCQlyZXR1cm4gMTsKCglzID0gMzsvL9GB0YLQsNGA0YIKCWUgPSA0Oy8v0LrQvtC90LXRhgoJcCA9IGdyYXBoX2JmcyhnLCBuLCBzLCBlLCAmbSk7CglpZihwICE9IE5VTEwpewoJCXByaW50ZigicGF0aDogIik7CgkJZm9yKGkgPSAwOyBpIDwgbTsgKytpKQoJCQlwcmludGYoIiV1ICIsIHBbaV0pOwoJCXB1dGNoYXIoJ1xuJyk7CgoJCWZyZWUocCk7Cgl9IGVsc2UKCQlmcHV0cygiZXJyb3IgZmluZCBiZnMhXG4iLCBzdGRlcnIpOwoKCWdyYXBoX2ZyZWUoZywgbik7CglyZXR1cm4gMDsKfQoKLy/Qv9C+0LjRgdC6INCyINGI0LjRgNC40L3Rgwp3b3JkX3QqIGdyYXBoX2JmcyhieXRlX3QqKiBnLCBpbnQgbiwgd29yZF90IHMsIHdvcmRfdCBlLCBpbnQqIG0pewoJaW50ICAgICBpLCB5OwoJcXVldWVfdCBxOwoJdmVydF90KiB2czsKCXdvcmRfdCAgdiwgKnAsICpkLCAqajsKCglwICA9IE5VTEw7Cgl2cyA9ICh2ZXJ0X3QqKW1hbGxvYygoc2l6ZV90KW4gKiBzaXplb2YodmVydF90KSk7CglpZih2cyA9PSBOVUxMKQoJCXJldHVybiBOVUxMOwoJZm9yKGkgPSAwOyBpIDwgbjsgKytpKQoJCXZzW2ldLnAgPSB2c1tpXS52ID0gVVNIUlRfTUFYOwoJCgl2c1tzXS52ID0gMDsKCXF1ZXVlX2luaXQoJnEpOwoJcXVldWVfcHVzaCgmcSwgcyk7CgoJeSA9IDA7Cgl3aGlsZSghIHF1ZXVlX2VtcHR5KCZxKSl7CgkJdiA9IHF1ZXVlX2Zyb250KCZxKTsKCQlxdWV1ZV9wb3AoJnEpOwoJCWlmKHYgPT0gZSl7CgkJCXkgPSAxOwoJCQlicmVhazsKCQl9CgkJZm9yKGkgPSAwOyBpIDwgbjsgKytpKXsKCQkJaWYoKGdbdl1baV0gIT0gMCkgJiYgKHZzW2ldLnYgPiAodnNbdl0udiArIDEpKSl7CgkJCQlxdWV1ZV9wdXNoKCZxLCAod29yZF90KWkpOwoJCQkJdnNbaV0ucCA9IHY7CgkJCQl2c1tpXS52ID0gdnNbdl0udiArIDE7CgkJCX0KCQl9Cgl9CglxdWV1ZV9jbGVhcigmcSk7CgoJaWYoeSl7CgkJdiA9IGU7CgkJaSA9IDE7CgkJd2hpbGUodiAhPSBzKXsKCQkJdiA9IHZzW3ZdLnA7CgkJCSsraTsKCQl9CgkJcCA9ICh3b3JkX3QqKW1hbGxvYygoc2l6ZV90KWkgKiBzaXplb2Yod29yZF90KSk7CgkJaWYocCA9PSBOVUxMKQoJCQlyZXR1cm4gTlVMTDsKCgkJZCA9IHA7CgkJZm9yKCpkKysgPSBlOyBlICE9IHM7IGUgPSB2c1tlXS5wKQoJCQkqZCsrID0gdnNbZV0ucDsKCQkKCQlmb3IoLS1kLCBqID0gcDsgaiA8IGQ7ICsraiwgLS1kKXsKCQkJdiAgPSAqZDsKCQkJKmQgPSAqajsKCQkJKmogPSB2OwoJCX0KCQkqbSA9IGk7Cgl9CglmcmVlKHZzKTsKCXJldHVybiBwOwp9CgovKgrQstCy0L7QtCDQvdC10L7RgNC40LXQvdGC0LjRgNC+0LLQsNC90L3QvtCz0L4g0LPRgNCw0YTQsCwg0YTQvtGA0LzQsNGCCglOIC0g0LrQvtC7LdCy0L4g0LLQtdGA0YjQuNC9ICBNIC0g0LrQvtC7LdCy0L4g0YDRkdCx0LXRgAoqLwpieXRlX3QqKiBncmFwaF9pbnB1dChGSUxFKiBfaW4sIGludCogbil7CglpbnQgICAgICBpLCBqLCB2biwgZW0sIGEsIGI7CglieXRlX3QqKiBnOwoJaWYoKGZzY2FuZihfaW4sICIlZCAlZCIsICZ2biwgJmVtKSAhPSAyKSB8fCAodm4gPD0gMSkgfHwgKGVtIDw9IDEpKQoJCXJldHVybiBOVUxMOwoKCWcgPSAoYnl0ZV90KiopbWFsbG9jKChzaXplX3Qpdm4gKiBzaXplb2YoYnl0ZV90KikpOwoJaWYoZyA9PSBOVUxMKQoJCXJldHVybiBOVUxMOwoKCWZvcihpID0gMDsgaSA8IHZuOyArK2kpewoJCWdbaV0gPSAoYnl0ZV90KiljYWxsb2MoKHNpemVfdCl2biwgc2l6ZW9mKGJ5dGVfdCkpOwoJCWlmKGdbaV0gPT0gTlVMTCl7CgkJCWkgLT0gMTsKCQkJZ290byBlcnI7CgkJfQoJfQoKCWZvcihpID0gMDsgaSA8IGVtOyArK2kpewoJCWlmKGZzY2FuZihfaW4sICIlZCAlZCIsICZhLCAmYikgPT0gMil7CgkJCWlmKChhIDwgdm4pICYmIChiIDwgdm4pKQoJCQkJZ1thXVtiXSA9IGdbYl1bYV0gPSAxOwoJCX0gZWxzZQoJCQlicmVhazsKCX0KCSpuID0gdm47CglyZXR1cm4gZzsKZXJyOgoJZm9yKGogPSBpOyBqID49IDA7IC0taikKCQlmcmVlKGdbal0pOwoJZnJlZShnKTsKCXJldHVybiBOVUxMOwp9CgovL9GD0LTQsNC70LXQvdC40LUg0LPRgNCw0YTQsCDQuNC3INC/0LDQvNGP0YLQuAp2b2lkIGdyYXBoX2ZyZWUoYnl0ZV90KiogZywgaW50IG4pewoJaW50IGk7Cglmb3IoaSA9IDA7IGkgPCBuOyArK2kpCgkJZnJlZShnW2ldKTsKCWZyZWUoZyk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tCi8v0LLRgdGC0LDQstC60LAKaW50IHF1ZXVlX3B1c2gocXVldWVfdCogcSwgd29yZF90IHYpewoJbm9kZV90KiBwID0gKG5vZGVfdCopbWFsbG9jKHNpemVvZihub2RlX3QpKTsKCWlmKHAgIT0gTlVMTCl7CgkJcC0+diAgICA9IHY7CgkJcC0+bmV4dCA9IE5VTEw7CgkJaWYocS0+aCA9PSBOVUxMKQoJCQlxLT5oID0gcS0+dCA9IHA7CgkJZWxzZSB7CgkJCXEtPnQtPm5leHQgPSBwOwoJCQlxLT50ID0gcDsKCQl9Cgl9CglyZXR1cm4gKHAgIT0gTlVMTCk7Cn0KCi8v0LjQt9Cy0LvQtdGH0LXQvdC40LUKdm9pZCBxdWV1ZV9wb3AocXVldWVfdCogcSl7Cglub2RlX3QqIHQ7CglpZihxLT5oICE9IE5VTEwpewoJCXQgICAgPSBxLT5oOwoJCXEtPmggPSBxLT5oLT5uZXh0OwoJCWZyZWUodCk7CgkJaWYocS0+aCA9PSBOVUxMKQoJCQlxLT50ID0gTlVMTDsKCX0KfQoKLy/Rg9C00LDQu9C10L3QuNC1INCy0YHQtdGFCnZvaWQgcXVldWVfY2xlYXIocXVldWVfdCogcSl7Cgl3aGlsZSghIHF1ZXVlX2VtcHR5KHEpKQoJCXF1ZXVlX3BvcChxKTsKfQ==