#include #include #include #include int N; /* Počet nádraží */ struct vertex { /* Jeden vrchol, tedy půlka nástupiště */ int x, y; /* Nádraží a nástupiště */ int h; /* Která polovina to je: 0=levá, 1=pravá */ struct edge *left, *right; /* První hrana doleva a doprava */ struct vertex *next; /* Další vrchol ve frontě při hledání do šířky */ struct edge *back; /* Zpětný odkaz při hledání do šířky */ int flag; /* Univerzální značka, v klidu nulová */ }; int *N2V; /* Číslo vrcholu prvního nástupiště pro každé nádraží */ struct vertex *V; /* Pole vrcholů */ struct edge { /* Jedna hrana, tedy trať */ struct edge *next; /* Následující pro totéž nástupiště */ struct edge *twin; /* Sestřička v protisměru */ struct vertex *dest; /* Cílový vrchol */ int red; /* 0=modrá, 1=červená */ }; void *malloc_zero(unsigned int size) { /* Alokuje a vynuluje blok paměti */ void *x = malloc(size); if (!size) exit(1); memset(x, 0, size); return x; } void add_edge(struct vertex *x, struct vertex *y) { /* Přidá jednu hranu v obou směrech */ struct edge *e = malloc_zero(2*sizeof(struct edge)); struct edge *f = e+1; e->next = x->right; x->right = e; e->twin = f; e->dest = y; f->next = y->left; y->left = f; f->twin = e; f->dest = x; } void read_input(void) { /* Načte vstup a vytvoří graf */ scanf("%d", &N); /* Počet nádraží */ N2V = malloc_zero(sizeof(int) * (N+2)); for (int i=1; i<=N; i++) /* Počty nástupišť */ { int k; scanf("%d", &k); N2V[i+1] = N2V[i] + k; } int n = N2V[N+1]; /* Prvních n jsou levé poloviny, dalších n pravé */ V = malloc_zero(sizeof(struct vertex) * 2 * n); for (int i=1; i<=N; i++) /* Dělíme nástupiště na vrcholy */ for (int j=N2V[i]; jflag) { **qlastp = v; v->next = NULL; *qlastp = &v->next; v->back = back; v->flag = 1; } } struct vertex *find_improving_path(void) { /* Nalezne zlepšující cestu a vrátí, kde skončila */ struct vertex *queue = NULL, **qlast = &queue; for (int i=N2V[1]; ix != N || !queue->h)) { for (struct edge *e = queue->right; e; e=e->next) if (!e->red) /* Po modrých hranách doprava */ add_to_queue(&qlast, e->dest, e); for (struct edge *e = queue->left; e; e=e->next) if (e->red) /* Po červených hranách doleva */ add_to_queue(&qlast, e->dest, e); queue = queue->next; } /* Ještě potřebujeme smazat všechny značky */ while (qfirst) { qfirst->flag = 0; qfirst = qfirst->next; } return queue; } void improve_along_path(struct vertex *v) { /* Zlepší podél nalezené cesty */ while (v->back) { v->back->red ^= 1; v->back->twin->red ^= 1; v = v->back->twin->dest; } } void find_tracks(void) { /* Nalezne podle vyvážené množiny trasy vlaků */ for (int i=N2V[1]; iright) && !e->red) v->right = e->next; if (!e) break; if (!v->h) printf("(%d,%d) ", v->x, v->y); v->right = e->next; v = e->dest; } if (v->h) putchar('\n'); } } int main(void) { read_input(); struct vertex *v; while (v = find_improving_path()) improve_along_path(v); find_tracks(); return 0; }