#include #include #include #include using namespace std; void printSet(set set) { for (auto it = set.begin(); it != set.end(); ++it) std::cout << *it << " "; cout << endl; } int main() { //nacitani, nalezeni zdroje a stoku int N, M; cin >> N >> M; //mnoziny pro nalezeni zdroje a stoku set sourceSet; set stockSet; //ulozeni grafu do matice sousednosti vector> mat; mat.insert(mat.end(), vector()); for(int i = 1; i <= N; ++i) { mat.insert(mat.end(), vector()); mat[i].insert(mat[i].end(), 0); for(int j = 1; j <= N; ++j) { mat[i].insert(mat[i].end(), 0); } sourceSet.insert(i); stockSet.insert(i); } int x, y; for(int i = 1; i <= M; ++i) { cin >> x >> y; mat[x][y] = 1; auto pos = sourceSet.find(y); if(pos != sourceSet.end()) { sourceSet.erase(pos); } pos = stockSet.find(x); if(pos != stockSet.end()) { stockSet.erase(pos); } } int source = *(sourceSet.begin()); int stock = *(stockSet.begin()); //cout << "source: " << *(sourceSet.begin()) << endl; //cout << "stock: " << *(stockSet.begin()) << endl; //odebrani prime hrany ze zdroje do stoku int toRemove = 0; if(mat[source][stock] == 1) { mat[source][stock] = 0; //cout << "edge to remove: " << source << " -> " << stock << " source to stok " << endl; toRemove++; } //prochazeni algoritmem BFS queue q; set open; q.push(source); int actual; while(!q.empty()) { actual = q.front(); q.pop(); for(int i = 1; i <= N; ++i) { if(mat[actual][i] == 0) { continue; } else if(i == stock) { continue; } //cout << "edge " << actual << " -> " << i << endl; if(open.find(i) == open.end()) { open.insert(i); q.push(i); } else { //zjisteni, zda ma i i jinou vstupni hranu bool hasEdge = false; for(int j = 1; j <= N; ++j) { if(j == actual) { continue; } if(mat[j][i] == 1) { hasEdge = true; break; } } if(hasEdge == false) { open.insert(i); q.push(i); hasEdge = true; } else { mat[actual][i] == 0; //cout << "edge to remove: " << actual << " -> " << i << endl; ++toRemove; } } } } cout << toRemove << endl; return 0; }