Dnevni plan

U fabrici postoji \(n\) zavisnih zadataka. Zavisnosti su zadate usmerenim vezama: ako postoji veza \(u \rightarrow v\), zadatak \(u\) mora biti završen pre zadatka \(v\). Zadaci koji nemaju nezavršene preduslove u tom trenutku smatraju se spremnim.

Potrebno je utvrditi da li je dati raspored moguć. Ako jeste moguć, odrediti minimalan broj dana \(d\) potrebanih da se završe svi zadaci.

Opis ulaza

Sa standardnog ulaza se unosi broj zadataka \(n\) (\(1 \leq n \leq 2 \cdot 10^5\)) i broj veza \(m\) (\(1 \leq m \leq 4 \cdot 10^5\)). U narednih \(m\) linija, unose se dva broja \(u\) i \(v\) (\(1 \leq u, v \leq n\), \(u \noteq v\)).

Opis izlaza

Na standardni izlaz ispisati minimalan broj dana \(d\), koji je potreban da se završe svi zadaci. Ukoliko nije moguće odrediti raspored, ispisati -1.

Primer 1

Ulaz

5 4 1 3 2 3 3 4 2 5

Izlaz

3

Objašnjenje

Prvog dana se završe zadaci 1 i 2. Drugog dana se završe zadaci 3 i 5. I trećeg dana se završi zadatak 4.

Primer 2

Ulaz

3 3 1 2 2 3 3 1

Izlaz

-1

Objašnjenje

Zadatak 2 je uslovljen zadatkom 1; zadatak 1 je uslovljen zadatkom 3; i zadatak 3 je uslovljen zadatkom 2. Ni jedan zadatak se ne može završiti.

Rešenje

Opis glavnog rešenja

U ovom bloku se opisuje glavno rešenje zadatka.

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class Graph{
        private:
                vector<vector<int>> adj_list;
                vector<int> in_degs;
        public:
                void init(int num_of_nodes){
                        adj_list.resize(num_of_nodes);
                        in_degs.resize(num_of_nodes, 0);
                }

                void add_edge(int u, int v){
                        adj_list[u].push_back(v);
                        in_degs[v]++;
                }

                int top_sort(){
                        
                        queue<int> q;
                        int brD = 0;

                        for(int i = 0; i < in_degs.size(); i++)
                                if(in_degs[i] == 0)
                                        q.push(i);

                        if(q.empty())
                                return -1;

                        q.push(-1);

                        while(!q.empty()){
                                int v = q.front();
                                q.pop();

                                if(v == -1){
                                        brD++;
                                        if(q.empty())
                                                break;
                                        q.push(-1);
                                        continue;
                                }

                                for(int u : adj_list[v]){
                                        in_degs[u]--;
                                        if(in_degs[u] == 0)
                                                q.push(u);
                                }
                        }

                        for(int i = 0; i < in_degs.size(); i++)
                                if(in_degs[i] > 0)
                                        return -1;

                        return brD;
                }

};


int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(0);

        int n, m;
        cin >> n >> m;
        
        Graph *G = new Graph();
        G->init(n);

        int u, v;
        for(int i = 0; i < m; i++){
                cin >> u >> v;
                G->add_edge(u-1, v-1);
        }


        cout << G->top_sort() << endl;

        return 0;
}