Matrix_code

graph - Dominator Tree

Feb 13th, 2017 (edited)
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.83 KB | None | 0 0
  1. /*
  2. Dominator tree of a undirected graph.
  3. 1. Create a Dag
  4. 2. For each node, par = LCA( of its parent in Dag)
  5. 3. Sparse Table.
  6.  
  7. */
  8. #include <bits/stdc++.h>
  9. using namespace std;
  10.  
  11. #define F first
  12. #define S second
  13.  
  14.  
  15. const int N = 2e5+5;
  16. const int LG = 18;
  17. long long d[N];
  18. bool vis[N];
  19. long long INF = 1e18;
  20. vector<pair<int,long long> > G[N] ,Dag[N];
  21. vector<int> top;
  22. vector<int> par[N];
  23. int P[N][LG];
  24. int lev[N];
  25. vector < int > T[N];
  26. int Size[N];
  27.  
  28. int n,m,s,u,v,w;
  29.  
  30. void Dijkastra(int s,int n)
  31. {
  32.    for(int i=0;i<=n;i++) d[i]=INF, vis[i] =0;
  33.    d[s]= 0;
  34.    set<pair<long long,int> > pq;
  35.    pq.insert(make_pair(d[s],s));
  36.    while(!pq.empty()){
  37.       auto p = *pq.begin(); pq.erase(pq.begin());
  38.       int u= p.S;
  39.       for(auto a: G[u]) {
  40.          if(d[a.F] > a.S + d[u]) {
  41.             d[a.F] = a.S + d[u];
  42.             pq.insert(make_pair(d[a.F] , a.F));
  43.          }
  44.       }
  45.    }
  46. }
  47.  
  48. void BuildDag(int n)
  49. {
  50.    for(int i=1;i<=n;i++) {
  51.       for(int j=0;j < G[i].size(); j++) {
  52.          int v = G[i][j].F ;
  53.          long long w = G[i][j].S;
  54.          if(d[v] != INF && d[i] != INF && d[v ] == d[i] + w) {
  55.             Dag[i].push_back(make_pair(v,w));
  56.             par[v].push_back(i);
  57.          }
  58.       }
  59.    }
  60. }
  61. void dfs(int s)
  62. {
  63.    if(vis[s]) return ;
  64.    vis[s] = 1;
  65.    for(auto a: Dag[s]) {
  66.       dfs(a.F);
  67.    }
  68.    top.push_back(s);
  69. }
  70. void Topsort(int s)
  71. {
  72.    memset(vis,0,sizeof vis);
  73.    top.clear();
  74.    dfs(s);
  75.    reverse(top.begin(), top.end());
  76. }
  77.  
  78. int LCA(int u,int v)
  79. {
  80.    if(lev[u] > lev[v]) swap(u,v);
  81.    int d = lev[v] - lev[u];
  82.    for(int i = LG - 1; i >= 0 ;  i -- ) if( d  &1<<i) v = P[v][i];
  83.    
  84.    if(u==v) return u;
  85.    
  86.    for(int i = LG-1; i >= 0 ; i -- ) {
  87.       if(P[u][i] != P[v][i]) {
  88.          u = P[u][i];
  89.          v = P[v][i];
  90.       }
  91.    }
  92.    return P[v][0];
  93. }
  94. void BuildDom(int n)
  95. {
  96.    memset(P,-1,sizeof P);
  97.    memset(lev,0,sizeof lev);
  98.    for(int i= 0;i < top.size(); i++ ) {
  99.       int u = top[i];
  100.       if(par[u].size()){
  101.          int lca = par[u][0];
  102.          for(int i = 1; i < par[u].size(); i ++ ) {
  103.             lca = LCA(lca, par[u][i]);
  104.          }
  105.          P[u][0] = lca;
  106.          lev[u] = 1 + lev[lca];
  107.          T[lca].push_back(u);
  108.          for(int j= 1; j < LG ; j ++ ) if(P[u][j-1] !=-1 ) P[u][j] = P[P[u][j-1]][j-1];
  109.       }
  110.    }
  111. }
  112. void Dfs(int u)
  113. {
  114.    Size[u] = 1;
  115.    for(auto a: T[u]) {
  116.       Dfs(a);
  117.       Size[u] += Size[a];
  118.    }
  119. }
  120. int main()
  121. {
  122.    scanf("%d %d %d",&n,&m,&s);
  123.    for(int i=0;i<m;i++){
  124.       scanf("%d %d %d",&u,&v,&w);
  125.       G[u].push_back(make_pair(v,w));
  126.       G[v].push_back(make_pair(u,w));
  127.    }
  128.    Dijkastra(s,n);
  129.    BuildDag(n);
  130.    Topsort(s);
  131.    BuildDom(n);
  132.    Dfs(s);
  133.    int ans = 0;
  134.    for(int i = 1;i <= n;i ++) {
  135.       if(i==s) continue;
  136.       ans = max( ans, Size[i]);
  137.    }
  138.    printf("%d\n",ans);
  139. }
Add Comment
Please, Sign In to add comment