BotByte

Untitled

Mar 8th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.45 KB | None | 0 0
  1. /********* Dominator Tree for Directed General Graph ***********/
  2. /*
  3. Sample Problem: Given an undirected graph with N nodes and M edges, calculate the number
  4. of unordered pairs(X, Y) such there exists two paths, one from node 1 to node X, and
  5. another from node 1 to node Y, such that they don't share any node except node 1.
  6. */
  7.  
  8. #include<bits/stdc++.h>
  9.  
  10. using namespace std;
  11.  
  12. typedef long long int LL;
  13.  
  14. const int N = int(1e5)+10;
  15. const int M = int(5e5)+10;
  16. vector<int> g[N];
  17. vector<int> tree[N],rg[N],bucket[N];
  18. int sdom[N],par[N],dom[N],dsu[N],label[N];
  19. int arr[N],rev[N],T;
  20. LL ans;
  21. int Find(int u,int x=0)
  22. {
  23. if(u==dsu[u])return x?-1:u;
  24. int v = Find(dsu[u],x+1);
  25. if(v<0)return u;
  26. if(sdom[label[dsu[u]]] < sdom[label[u]])
  27. label[u] = label[dsu[u]];
  28. dsu[u] = v;
  29. return x?v:label[u];
  30. }
  31. void Union(int u,int v) //Add an edge u-->v
  32. {
  33. dsu[v]=u; //yup,its correct :)
  34. }
  35. void dfs0(int u)
  36. {
  37. T++;arr[u]=T;rev[T]=u;
  38. label[T]=T;sdom[T]=T;dsu[T]=T;
  39. for(int i=0;i<g[u].size();i++)
  40. {
  41. int w = g[u][i];
  42. if(!arr[w])dfs0(w),par[arr[w]]=arr[u];
  43. rg[arr[w]].push_back(arr[u]);
  44. }
  45. }
  46. int dfs(int u,int p)
  47. {
  48. int ret=1;
  49. for(int i=0;i<tree[u].size();i++)
  50. {
  51. int w = tree[u][i];
  52. if(w==p)continue;
  53. int x = dfs(w,u);
  54. if(u==1)ans -= (x*1ll*(x-1ll))/2ll;
  55. ret+=x;
  56. }
  57. return ret;
  58. }
  59. int main()
  60. {
  61. int n,m;
  62. scanf("%d %d", &n, &m);
  63. for(int i=0;i<m;i++)
  64. {
  65. int u,v;
  66. scanf("%d %d", &u, &v);
  67. g[u].push_back(v);
  68. }
  69. //Build Dominator tree
  70. dfs0(1);
  71. n=T;
  72. for(int i=n;i>=1;i--)
  73. {
  74. for(int j=0;j<rg[i].size();j++)
  75. sdom[i] = min(sdom[i],sdom[Find(rg[i][j])]);
  76. if(i>1)bucket[sdom[i]].push_back(i);
  77. for(int j=0;j<bucket[i].size();j++)
  78. {
  79. int w = bucket[i][j];
  80. int v = Find(w);
  81. if(sdom[v]==sdom[w])dom[w]=sdom[w];
  82. else dom[w] = v;
  83. }
  84. if(i>1)Union(par[i],i);
  85. }
  86. for(int i=2;i<=n;i++)
  87. {
  88. if(dom[i]!=sdom[i])
  89. dom[i]=dom[dom[i]];
  90. tree[rev[i]].push_back(rev[dom[i]]);
  91. tree[rev[dom[i]]].push_back(rev[i]);
  92. }
  93. //done :)
  94. ans = (n*1ll*(n-1ll))/2ll;
  95. dfs(1,1);
  96. printf("%lld\n", ans);
  97. return 0;
  98. }
  99.  
  100. /*
  101. 6 6
  102. 1 2
  103. 1 3
  104. 1 4
  105. 2 5
  106. 2 6
  107. 3 6
  108. */
  109. /*
  110. 14
  111. */
Advertisement
Add Comment
Please, Sign In to add comment