Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #define forn(i, n) for(int i = 1; i <= n; ++i)
- #define MAX 1001
- using namespace std;
- vector<vector<int>>graph(MAX);
- vector<vector<int>>reversed(MAX);
- struct Edge {
- int from;
- int to;
- };
- vector <Edge> edges;
- bool mark[MAX];
- int components[MAX];
- vector <int> oto;
- int n, m, counter; //counter - для подсчета компонент, чтобы вывести количество ребер, просто прибавим единицу...
- void dfs_s(int v) {
- mark[v] = 1;
- for( int x : graph[v]) {
- if (mark[x] == 0)
- dfs_s(x);
- }
- oto.push_back(v);
- }
- void dfs_r(int v) { //DFS по обратным ребрам
- if (components[v]) return ;
- components[v] = counter; //пометили вершинку из компоненты, аналог массива mark[MAX]
- for (int x : reversed[v]) {
- dfs_r(x);
- }
- }
- void top_sort() {
- forn(i, n)
- mark[i] = 0;
- oto.clear();
- forn(i, n)
- if(!mark[i])
- dfs_s(i);
- reverse(oto.begin(), oto.end());
- //for (int i: oto)
- // cout << i << " ";
- return;
- }
- int components_coloring() {
- counter = 0;
- for (int a = 1; a <= n; a++)
- if (!components[a]) {
- counter++;
- dfs_r(a);
- }
- return counter;
- }
- int main() {
- ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
- cin >> n >> m;
- int u, v;
- counter = 0; //счетчик компонент сильной связности
- int ce = 0; //счетчик ребер в конденсации
- forn(i, m) { //считали граф
- cin >> v >> u;
- graph[v].push_back(u);
- edges.push_back({v, u});
- }
- forn(i, n) { //перевернули граф, чтобы проходиться по обратным ребрам
- for (int x : graph[i])
- reversed[i].push_back(x);
- }
- top_sort(); //топологическая сортировка
- components_coloring();
- for(auto x : edges) {
- if (components[x.from] == components[x.to])
- ce++;
- }
- cout << ce << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement