Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <cstdio>
- #include <unordered_set>
- #include <map>
- #include <stack>
- #define task "NEWROADS"
- using namespace std;
- using ll = long long;
- using ld = long double;
- const int N = 2e5 + 2;
- int n, m;
- vector<int> s;
- unordered_set<int> adj[N], nadj[N];
- int lt[N];
- ll cnt[N], have[N];
- int l(0), a[N], b[N];
- bool vis[N];
- void Read(){
- cin >> n >> m;
- for(int i = 1; i <= m; ++i){
- cin >> a[i] >> b[i];
- if(adj[a[i]].find(b[i]) != adj[a[i]].end()){
- --i; --m;
- continue;
- }
- adj[a[i]].insert(b[i]);
- nadj[b[i]].insert(a[i]);
- }
- }
- void dfs(int v){
- vis[v] = 1;
- for(auto i : adj[v])
- if(!vis[i])
- dfs(i);
- s.push_back(v);
- }
- void dfs_component(int v){
- lt[v] = l;
- ++cnt[l];
- for(auto i : nadj[v])
- if(lt[i] == 0)
- dfs_component(i);
- }
- void Kosaraju(){
- for(int i = 1; i <= n; ++i)
- if(!vis[i])
- dfs(i);
- while(s.size()){
- int c = s.back();
- s.pop_back();
- if(lt[c] != 0)
- continue;
- ++l;
- dfs_component(c);
- }
- }
- void Solve(){
- Kosaraju();
- for(int i = 1; i <= m; ++i)
- if(lt[a[i]] == lt[b[i]])
- ++have[lt[a[i]]];
- ll ans = 0;
- for(int i = 1; i <= l; ++i)
- ans += cnt[i] * (cnt[i] - 1ll) - have[i];
- cout << ans;
- }
- main(){
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0); if(fopen(task".INP", "r"))
- freopen(task".INP", "r", stdin),
- freopen(task".OUT", "w", stdout);
- Read();
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment