using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace idos { class Program { class stanica { public string meno; public int kod; public bool hotovy; //ci je cesta do daneho vrcholu definitivne najkratsia public int cas; //cas za ktory sa do nej vieme dostat public stanica pred; //predchodca na ceste do stanice public hrana ktorouSmePrisli; public List susedia; public stanica(string meno, int kod) { this.meno = meno; this.kod = kod; this.hotovy = false; this.cas = int.MaxValue; this.pred = null; this.ktorouSmePrisli = null; this.susedia = new List(); } } class hrana { public int index; //kod susedneho vrcholu public string vlak; public int dlzka; //dlzka cesty v minutach public int odchod; //v akom case odchadza public hrana(int i, string v, int d, int o) { this.index = i; this.vlak = v; this.dlzka = d; this.odchod = o; } } static bool ziskajIndex(string s, ref int i) { foreach (stanica x in graf) { if (x.meno.ToLower() == s.ToLower()) { i = x.kod; return true; } } return false; } static void nacitajGraf(string subor) { StreamReader r = new StreamReader(subor); int pocetStanic = Convert.ToInt32(r.ReadLine()); graf = new List(); for (int i = 0; i < pocetStanic; i++) { string menoStanice = r.ReadLine(); graf.Add(new stanica(menoStanice, i)); } int pocetVlakov = Convert.ToInt32(r.ReadLine()); for (int i = 0; i < pocetVlakov; i++) { string menoVlaku = r.ReadLine(); char[] oddelovace = { ' ' }; string[] draha = (r.ReadLine()).Split(oddelovace, StringSplitOptions.RemoveEmptyEntries); int predchodca = Convert.ToInt32(draha[0]); int vCase = Convert.ToInt32(draha[1]); for (int j = 2; j < draha.Length; j = j + 2) { int indexStanice = Convert.ToInt32(draha[j]); int prichodVcase = Convert.ToInt32(draha[j + 1]); //dlzka cesty je rozdiel medzi prichodom do predchodcu a prichodom do nasledovnika graf[predchodca].susedia.Add(new hrana(indexStanice, menoVlaku, prichodVcase - vCase, vCase)); predchodca = indexStanice; vCase = prichodVcase; } } } static bool najdiCestu(int start, int ciel, int cas) { foreach (hrana x in graf[start].susedia) { if (!graf[x.index].hotovy && //ak stanica este neni definitivna graf[start].cas <= x.odchod && //ak vlak do stanice odchadza az ked sme na stanici aj my graf[x.index].cas > x.odchod + x.dlzka) //ak je aktualny cas vacsi ako to co stravime cakanim a samotnou cestou... //ak cesta do vrcholu este nie je definitivna // a hranou x sa do vrcholu dostaneme v lepsom //case v akom sme sa dokazali doteteraz //tak zmenime udaje { graf[x.index].cas = x.odchod + x.dlzka; graf[x.index].pred = graf[start]; graf[x.index].ktorouSmePrisli = x; } } int minCas = int.MaxValue; stanica taKtoruUzavreme = null; foreach (stanica s in graf) { if (!s.hotovy && s.cas < minCas) { taKtoruUzavreme = s; minCas = s.cas; } } if (taKtoruUzavreme != null) { taKtoruUzavreme.hotovy = true; if (taKtoruUzavreme.kod != ciel) { if (najdiCestu(taKtoruUzavreme.kod, ciel, taKtoruUzavreme.cas)) { return true; } } else return true; } return false; } static void vynulujGraf() { foreach (stanica x in graf) { x.cas = int.MaxValue; x.pred = null; x.ktorouSmePrisli = null; x.hotovy = false; } } static void zrekapitulujCestu(Stack z) { stanica vrch = z.Peek(); if (vrch.pred != null) { z.Push(vrch.pred); zrekapitulujCestu(z); } else { while (z.Count != 0) { stanica p = z.Pop(); stanica nasledovnik = z.Pop(); while (z.Count != 0 && z.Peek().ktorouSmePrisli.vlak == nasledovnik.ktorouSmePrisli.vlak) { nasledovnik = z.Pop(); } if (z.Count != 0) z.Push(nasledovnik); Console.WriteLine("o {0} ideme z {1} vlakom {2} do {3} a dorazime o {4}", nasledovnik.ktorouSmePrisli.odchod, p.meno, nasledovnik.ktorouSmePrisli.vlak, nasledovnik.meno, nasledovnik.cas); } } } static List graf; static void Main(string[] args) { nacitajGraf(args[0]); string prikaz = Console.ReadLine(); while (prikaz != "exit") { char[] oddelovace = { '\t', ' ' }; string[] rozdeleny = prikaz.Split(oddelovace, StringSplitOptions.RemoveEmptyEntries); int start = 0; int ciel = 0; if (ziskajIndex(rozdeleny[0], ref start) && ziskajIndex(rozdeleny[1], ref ciel)) { int cas = Convert.ToInt32(rozdeleny[2]); //uzavrieme startovaci vrchol graf[start].cas = cas; graf[start].pred = null; graf[start].hotovy = true; if (najdiCestu(start, ciel, cas)) { Stack zasobnik = new Stack(); zasobnik.Push(graf[ciel]); zrekapitulujCestu(zasobnik); vynulujGraf(); } else { Console.WriteLine("cesta neexistuje"); vynulujGraf(); } } else Console.WriteLine("neplatny prikaz"); prikaz = Console.ReadLine(); } } } }