// Řešení 34-5-2 časoprostorovou simulací // Napsal Martin Medvěd Mareš #include #include #include #include #include #include using namespace std; #define MAXN 600 // Maximální počet vrcholů #define MAXT 300000 // Maximální doba trvání veletrhu #define INFTY 1000000000 // "nekonečno" #if 0 #define DBG(...) printf(__VA_ARGS__) #else #define DBG(...) do { } while (0) #endif // Reprezentace vstupu int N, M, U, T; struct udalost; struct hrana { int kam; int delka; }; struct vrchol { vector hrany; udalost *bezi_udalost; // Jaká událost zrovna ve vrcholu probíhá }; vector vrcholy; struct udalost { int id; // číslo události ve vstupu int kde; int zacatek, konec; // konec = zacatek + delka bool operator < (const udalost &y) const { return zacatek < y.zacatek; } }; vector udalosti; // Časoprostorový graf struct stav { int skore; int odkud; }; stav stavy[MAXT+1][MAXN]; // Čtení vstupu void nacti_vstup() { scanf("%d%d%d", &N, &M, &U); assert(N > 0 && N <= MAXN); assert(M >= 0); assert(U > 0); vrcholy.resize(N); for (int i=0; i= 0 && x < N); assert(y >= 0 && y < N); assert(x != y); hrana h; h.kam = y; h.delka = d; vrcholy[x].hrany.push_back(h); } for (int i=0; i= 0 && u.kde < N); assert(u.zacatek >= 0 && u.zacatek < MAXT); assert(delka > 0 && u.zacatek + delka <= MAXT); u.id = i; u.konec = u.zacatek + delka; udalosti.push_back(u); T = max(T, u.konec); } } // Prohledávání časoprostoru void simulace() { for (int t=0; t<=T; t++) { for (int i=0; i 0) ? i : -1; } } stavy[0][0].skore = 0; int t = 0; unsigned int ui = 0; while (t <= T) { for (int i=0; i 0 && stavy[t-1][i].skore > -INFTY) { // Čekáme v tomto vrcholu, možná +1 za událost int skore = stavy[t-1][i].skore; if (v->bezi_udalost) skore++; if (skore > stavy[t][i].skore) { stavy[t][i].skore = skore; stavy[t][i].odkud = i; } } for (auto &h: v->hrany) { int t2 = t + h.delka; if (t2 <= T && stavy[t2][h.kam].skore < stavy[t][i].skore) { stavy[t2][h.kam].skore = stavy[t][i].skore; stavy[t2][h.kam].odkud = i; } } DBG("@%d v=%d s=%d o=%d u=%d\n", t, i, stavy[t][i].skore, stavy[t][i].odkud, v->bezi_udalost ? v->bezi_udalost->id : -1); } // Vypneme události, které doběhly for (int i=0; ikonec <= t) vrcholy[i].bezi_udalost = NULL; // Nastartujeme nové události while (ui < udalosti.size() && udalosti[ui].zacatek == t) { udalost *u = &udalosti[ui]; assert(!vrcholy[u->kde].bezi_udalost); vrcholy[u->kde].bezi_udalost = u; ui++; } t++; } assert(ui == udalosti.size()); } // Vypisování trasy void vypis() { int skore = -INFTY; int kde = 0; for (int i=0; i skore) { skore = stavy[T][i].skore; kde = i; } } printf("%d\n", skore); int t = T; deque trasa; trasa.push_front(-1); while (t > 0) { trasa.push_front(kde); int odkud = stavy[t][kde].odkud; DBG(">> t=%d kde=%d odkud=%d\n", t, kde, odkud); if (odkud == kde) t--; else { for (hrana &h: vrcholy[odkud].hrany) if (h.kam == kde) { t -= h.delka; kde = odkud; break; } assert(kde == odkud); } } kde = 0; int cekej = 0; for (auto kam: trasa) { DBG("<< kam=%d\n", kam); if (kam == kde) cekej++; else { if (cekej > 0) printf("C %d\n", cekej); if (kam >= 0) printf("P %d\n", kam); kde = kam; cekej = 0; } } } // A teď všechno poskládat dohromady int main() { nacti_vstup(); sort(udalosti.begin(), udalosti.end()); simulace(); vypis(); return 0; }