Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.54 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef long double ld;
  7. typedef unsigned long long ull;
  8. typedef pair<ll,ll> ii;
  9. typedef vector<ll> vi;
  10. typedef vector< ii > vii;
  11.  
  12. #define INF 0x3F3F3F3F
  13. #define LINF 0x3F3F3F3F3F3F3F3FLL
  14. #define pb push_back
  15. #define mp make_pair
  16. #define pq priority_queue
  17. #define LSONE(s) ((s)&(-s)) //LASTBIT
  18. #define DEG_to_RAD(X)   (X * PI / 180)
  19. #define F first
  20. #define S second
  21. #define PI 2*acos(0)
  22.  
  23. #ifdef ONLINE_JUDGE
  24. #define debug(args...)
  25. #else
  26. #define debug(args...) fprintf(stderr,args)
  27. #endif
  28.  
  29. //////////////////////
  30. int dx[] = {1,-1,0,0};
  31. int dy[] = {0,0,-1,1};
  32. //////////////////////
  33.  
  34. /*
  35.   Author: Junior Andrade
  36. */
  37.  
  38. void arquivo(){
  39.   freopen("","r",stdin);
  40.   freopen("","w",stdout);
  41. }
  42.  
  43. const int N = 200000;
  44.  
  45. vi g[N], tree[N], rg[N], bucket[N];
  46. int sdom[N], par[N], dom[N], dsu[N], label[N];
  47. int arr[N], rev[N], T;
  48. int n,m;
  49.  
  50.  
  51.  
  52. int Find(int u,int x=0)
  53. {
  54.   if(u==dsu[u])return x?-1:u;
  55.   int v = Find(dsu[u],x+1);
  56.   if(v<0)return u;
  57.   if(sdom[label[dsu[u]]] < sdom[label[u]])
  58.     label[u] = label[dsu[u]];
  59.   dsu[u] = v;
  60.   return x?v:label[u];
  61. }
  62. void Union(int u,int v) //Add an edge u-->v
  63. {
  64.   dsu[v]=u;   //yup,its correct :)
  65. }
  66.  
  67. void dfs0( int x ){
  68.     T++; arr[x] = T; rev[T] = x;
  69.     label[T] = T; sdom[T] = T; dsu[T] = T;
  70.     for(int i=0;i<g[x].size();++i){
  71.         int y = g[x][i];
  72.         if( !arr[y] ){
  73.             dfs0(y);
  74.             par[arr[y]] = arr[x];
  75.         }
  76.         rg[arr[y]].pb(arr[x]);
  77.     }
  78. }
  79.  
  80. void processTree(){
  81.   T = 0;
  82.   dfs0(1);
  83.   n = T;
  84.   for(int i=n;i>=1;i--)
  85.   {
  86.     for(int j=0;j<rg[i].size();j++) sdom[i] = min(sdom[i],sdom[Find(rg[i][j])]);
  87.     if(i>1) bucket[sdom[i]].pb(i);
  88.     for(int j=0;j<bucket[i].size();j++)
  89.     {
  90.       int w = bucket[i][j];
  91.       int v = Find(w);
  92.       if(sdom[v]==sdom[w]) dom[w]=sdom[w];
  93.       else dom[w] = v;
  94.     }
  95.     if(i>1)Union(par[i],i);
  96.   }
  97.   for(int i=2;i<=n;i++)
  98.   {
  99.     if(dom[i]!=sdom[i]) dom[i]=dom[dom[i]];
  100.     tree[rev[i]].pb(rev[dom[i]]);
  101.     tree[rev[dom[i]]].pb(rev[i]);
  102.   }
  103. }
  104.  
  105. ll subSize[N];
  106. ll ans;
  107.  
  108. void dfs( int x, int ult ){
  109.   subSize[x] = 1;
  110.   for(int i=0;i<tree[x].size();++i){
  111.     int y = tree[x][i];
  112.     if( y == ult ) continue;
  113.     dfs(y,x);
  114.     subSize[x]+=subSize[y];
  115.     if( x == 1 ) ans -= (subSize[y]*1LL*(subSize[y]-1LL))/2LL;
  116.   }
  117. }
  118.  
  119. int main(){
  120.   //ios::sync_with_stdio(0);
  121.     scanf("%d %d",&n,&m);
  122.   for(int i=0;i<m;++i){
  123.     int x,y; scanf("%d %d",&x,&y);
  124.     g[x].pb(y);
  125.   }
  126.   processTree();
  127.   ans = (n*1LL*(n-1LL))/2LL;
  128.   dfs(1,1);
  129.   printf("%lld\n",ans);
  130.   return 0;
  131. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement