#include #include #include #include using namespace std; vector halda; struct hrana { int kam; int delka; }; // Funkce, která prohodí vrcholy se zadanými indexy v haldě void swap_halda(int i, int j, int v_halde[]) { int a = halda[i]; int b = halda[j]; v_halde[halda[i]] = j; v_halde[halda[j]] = i; halda[i] = b; halda[j] = a; return; } // Funkce, která probublá zadaný prvek nahoru void uprav_halda(int delka[], int v_halde[], int index) { // Dokud nejsme úplně nahoře v haldě a máme prohazovat, prohazujeme while (index > 0 && delka[halda[index]] < delka[halda[(index - 2) / 2]]) { swap_halda(index, (index - 2) / 2, v_halde); index = (index - 2) / 2; } return; } // Funkce, která zařadí prvek do haldy void push_halda(int delka[], int v_halde[], int vrchol) { halda.push_back(vrchol); // Prvek zařadíme na konec haldy v_halde[vrchol] = halda.size() - 1; uprav_halda(delka, v_halde, halda.size() - 1); // Necháme jej probublat nahoru return; } // Funkce, která vrátí nejmenší prvek z haldy a haldu přerovná int pop_halda(int delka[], int v_halde[]) { int ret = halda[0]; v_halde[ret] = -1; if (halda.size() == 1) { // Jestliže to byl jediný prvek v haldě, haldu vyprázdníme a prvek vrátíme halda.pop_back(); return ret; } // Poslední prvek zařadíme na vrchol haldy (níže jej necháme spadnout na příslušné místo) halda[0] = halda.back(); halda.pop_back(); v_halde[halda[0]] = 0; int i = 0; int j; // Přerovnávání haldy while (2*i + 1 <= halda.size()) { // i je index našeho prvku a j je index nejmenšího z trojice "náš prvek a jeho dva synové" j = i; if (delka[halda[2*i + 1]] < delka[halda[j]]) j = 2*i + 1; if (2*i + 2 <= halda.size() && delka[halda[2*i + 2]] < delka[halda[j]]) j = 2*i + 2; if (i == j) { // Pokud je nejmenší náš prvek, ukončíme swapování break; } swap_halda(i, j, v_halde); } return ret; } /* * Formát vstupu (program čte ze standardního vstupu): * 1. řádek: N M * 2. řádek: start cil - čísla startovního a cílového vrcholu * následuje M řádků s čísly i, j a z značící hranu mezi vrcholy i a j délky z */ int main(int argc, char** argv) { int N, M, start, cil, a; scanf("%d%d", &N, &M); scanf("%d%d", &start, &cil); vector hrany[N]; int delka[N]; // Pole obsahující délku nejkratší cesty do vrcholu int pocet[N]; // Pole obsahující počet nejkratších cest do vrcholu int v_halde[N]; // Pole určující kde v haldě se daný vrchol nachází for (int i = 0; i < N; ++i) { delka[i] = -1; pocet[i] = 0; v_halde[i] = -1; } // Načítání vstupu struct hrana nova_hrana; for (int i = 0; i < M; ++i) { scanf("%d%d%d", &a, &(nova_hrana.kam), &(nova_hrana.delka)); hrany[a].push_back(nova_hrana); } // Inicializace pro startovní vrchol delka[start] = 0; pocet[start] = 1; halda.push_back(start); int vychozi; int koncovy; int delka_hrany; // Procházíme haldu while (!halda.empty()) { vychozi = pop_halda(delka, v_halde); // Procházíme všechny hrany z vrcholu for (int i = 0; i < hrany[vychozi].size(); ++i) { koncovy = hrany[vychozi][i].kam; delka_hrany = hrany[vychozi][i].delka; if (delka[koncovy] == -1) { // Vrchol jsme ještě neviděli - nastavíme proměnné a zařadíme do haldy delka[koncovy] = delka[vychozi] + delka_hrany; pocet[koncovy] = pocet[vychozi]; push_halda(delka, v_halde, koncovy); } else if (delka[koncovy] > delka[vychozi] + delka_hrany) { // Našli jsme kratší cestu - upravíme proměnné a umístění v haldě delka[koncovy] = delka[vychozi] + delka_hrany; pocet[koncovy] = pocet[vychozi]; uprav_halda(delka, v_halde, koncovy); } else if (delka[koncovy] == delka[vychozi] + delka_hrany) { // Našli jsme stejně dlouhou nejkratší cestu - zvedneme počet hran pocet[koncovy] += pocet[vychozi]; } // Pokud jsme našli delší cestu neděláme nic } } printf("%d\n", pocet[koncovy]); return 0; }