HDU4694 支配树裸题 Important Sisters

来源:互联网 发布:ubuntu apt get 换源 编辑:程序博客网 时间:2024/06/05 20:30

大家都很强, 可与之共勉 。

我觉得这很公正!

题意
给张图,然后求n到每个点的必经点的编号之和。

当然数据有锅,到不了输出0。

这是一道裸体

注意清零。

# include <bits/stdc++.h>inline int read ( )  {    register int x, c ;    bool opt ( 1 ) ;    while ( ! isdigit ( c = getchar ( ) ) && ( c ^ 45 ) && ( c ^ -1 ) ) ;    if ( c == -1 )  return -1 ;    if ( c == 45 )  c = getchar ( ), opt = 0 ;    for ( x = -48 + c ; isdigit ( c = getchar ( ) ) ; ( x *= 10 ) += c - 48 ) ;    return opt ? x : -x ;}# define N 50010# define M 100010struct edge  {    int to ;  edge* nxt ;} ;struct Graph  {    edge g [M << 1] ;    edge *head [N], *NewEdge ;    Graph ( )  {  NewEdge = g ;  memset ( head, 0, sizeof head ) ;  }    inline void add_edge ( int u, int v )  {        *( ++ NewEdge ) = ( edge ) {  v, head [u]  } ; head [u] = NewEdge ;    }    inline void clear ( )  {        NewEdge = g ;        memset ( head, 0, sizeof head ) ;    }    inline edge*& operator [] ( const int& u )  {  return head [u] ;  }} ;namespace pbds  {    inline bool cmp ( const int&, const int& ) ;    struct DominatorTree  {        Graph cur, rev ;        int ufs [N], val [N] ; // Union-Find-Set        int fa [N], dfn [N], id [N], idx ;  // father on Dfs Tree, Dfs order, Dfs id ;        int sdom [N], idom [N] ;  // half Dominate point, nearest  Dominate point        Graph dom ;  // save v that sdom [v] is u, at last it is Dominate Tree ;        inline void clear ( )  {            idx = 0 ;            memset ( dfn, 0, sizeof dfn ) ;            cur.clear ( ), rev.clear ( ) ;        }        inline void add_edge ( int u, int v )  {            cur.add_edge ( u, v ), rev.add_edge ( v, u ) ;        }        inline void dfs ( int u )  {            id [dfn [u] = ++ idx] = u ;            for ( edge* it = cur [u] ; it ; it = it -> nxt )  {                if ( ! dfn [it -> to] )  {                    fa [it -> to] = u ;                    dfs ( it -> to ) ;                }            }        }        inline int findfa ( int x )  {            if ( x == ufs [x] ) return x ;            int y = findfa ( ufs [x] ) ;            if ( cmp ( sdom [val [ufs [x]]], sdom [val [x]] ) ) val [x] = val [ufs [x]] ;            return ufs [x] = y ;        }        void build ( const int& s, const int& n )  {            for ( register int i = 1 ; i <= n ; ++ i )  ufs [i] = val [i] = sdom [i] = i ;            dfs ( s ) ;            for ( register int i = idx, u ; u = id [i], i > 1 ; -- i )  {                for ( edge* it = rev [u] ; it ; it = it -> nxt )                    if ( dfn [it -> to] )  {                        findfa ( it -> to ) ;                        sdom [u] = std :: min ( sdom [u], sdom [val [it -> to]], cmp ) ;                    }                dom.add_edge ( sdom [u], u ) ;                register int x = ( ufs [u] = fa [u] ) ;                for ( edge* it = dom [x] ; it ; it = it -> nxt )  {                    findfa ( it -> to ) ;                    idom [it -> to] = cmp ( sdom [val [it -> to]], fa [u]) ? val [it -> to] : fa [u] ;                }                dom [x] = 0 ;            }            for ( register int i = 2, u ; u = id [i], i <= idx ; ++ i )  {                ( idom [u] ^ sdom [u] ) ? idom [u] = idom [idom [u]] : 0 ;                dom.add_edge ( idom [u], u ) ;            }            clear ( ) ;        }    } T ;    inline bool cmp ( const int& u, const int& v )  { return T.dfn [u] < T.dfn [v] ;  }}long long ans [N] ;# undef N# undef MGraph* New ;inline void Dfs ( int u, int fr )  {    for ( edge* it = (*New) [u] ; it ; it = it -> nxt )  {        if ( it -> to ^ fr )  {            ans [it -> to] += ans [u] ;            Dfs ( it -> to, u ) ;        }    }}int main ( )  {    int n, m ;    while ( ( ~ ( n = read ( ) ) ) && ( ~ ( m = read ( ) ) ) )  {        while ( m -- )  {            int u ( read ( ) ), v ( read ( ) ) ;            pbds :: T.add_edge ( u, v ) ;        }        pbds :: T.build ( n, n ) ;        New = & pbds :: T.dom ;        for ( int i = 1 ; i <= n ; ++ i )  ans [i] = i ;        Dfs ( n, 0 ) ;        pbds :: T.dom.clear ( ) ;        for ( int i = 1 ; i <= n ; ++ i )  {            printf ( "%lld%c", ( ans [i] == i && n != i ) ? 0 : ans [i], ( i == n ) ? '\n' : ' ' ) ;        }    }}
原创粉丝点击