zoukankan      html  css  js  c++  java
  • 题解——home(必经路tarjan)

    题解——home(必经路tarjan)

    校内胡策题9月29日,ssw02估分150,实际得分9,这道题估分100,实际爆零

    题面搬运

    题面讲述了一个ssw02(假)在学校逃课,老师来抓ssw02的故事。

    输入:T组数据,每组数据一个图
    输出:T组数据,每组输出一定可以抓到ssw02的点的个数和点。

    思路

    首先我们想到,这些可以抓到ssw02的点一定是整个图的割点(如果你这没想到,可以去重新学习一下割点)。

    然后我们发现,啊,不对,有的割点好像走都不会走。然后我们加上以下代码,去找了一下那些点走过。

    void  dfs( int u , int fa ){
       anc[ u ] = fa , vis[ u ] = true ;
       for( register int i = head[ u ] ; i ; i = nex[ i ] ){
       	if( to[ i ] == fa )continue ;
       	if( vis[ to[ i ] ] )continue ; 
       	dfs( to[ i ] , u ) ;
       }
    }
    int now = N ; vis[ now ] = true ;//main中
    while( now != 1 )vis[ now ] = true , now = anc[ now ] ;
    
    

    然后,秒切样例,一交,100少了个0,只有10。

    我们来想想为什么?

    给出下面一组数据:

    10 11
    1 6
    6 10
    10 5
    5 8
    8 9
    9 3
    3 7
    7 2
    2 4
    5 6
    7 7
    

    仔细想想,发现我们可能先遍历5号点,再遍历6号点,然后5,6都通过了check。

    本质原因错在哪? --我们并没有保证 5 , 6 不在一个连通块内。

    然后Tarjan神仙又出现了,你没看错,tarjan在处理割点时还可以处理满足固定路径上点的不连通问题。

    我们这次先跑dfs得出一条简单路径,再跑tarjan,并且在tarjan判断割点上加上如下代码

    if( u != root || flag > 1 )cut[ u ] = 1 ;

    这样我们发现,会被之前已在搜索树上的点更新的目标点并不会被判断为必经路的割点(很显然割掉这个点后,目标点还和搜索树相连)

    御坂20001号( SXK )还有这样的理解,供大家参考

    然后没了。注意题目给的范围有坑。M>=2*N

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const  int  MAXN = 400010  ;
    int  head[ MAXN ] , to[ MAXN*2 ] , nex[ MAXN*2 ] ;
    int  dfn[ MAXN ] , low[ MAXN ] , anc[ MAXN ];
    int  T , N , M , tot = 1 , num , root ;
    bool vis[ MAXN ] , cut[ MAXN ] ;
    inline int read(){
    	int s=0 ; char g=getchar() ; while(g>'9'||g<'0')g=getchar() ;
    	while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
    }
    void  add( int x , int  y ){
        to[ ++tot ] = y , nex[ tot ] = head[ x ] , head[ x ] = tot ;
    }
    void  tarjan( int u ){
        dfn[ u ] = low[ u ] = ++num ;
        int  flag = 0 ; 
        for( register int i = head[ u ] ; i ; i = nex[ i ] ){
            int y = to[ i ] ;
            if( !dfn[ y ] ){
                tarjan( y ) ;
                low[ u ] = min( low[ u ] , low[ y ] ) ;
                if( low[ y ] >= dfn[ u ] && vis[ y ] ){
                    flag++ ;
                    if( u != root || flag > 1 )cut[ u ] = 1 ;
                }
            }
            else low[ u ] = min( low[ u ] , dfn[ y ] ) ;
        }
    }
    void  dfs( int u , int fa ){
    	anc[ u ] = fa , vis[ u ] = true ;
    	for( register int i = head[ u ] ; i ; i = nex[ i ] ){
    		if( to[ i ] == fa )continue ;
    		if( vis[ to[ i ] ] )continue ; 
    		dfs( to[ i ] , u ) ;
    	}
    }
    void  work(){
        N  = read() , M = read() ;
        for( register int i = 1 ; i <= M ; i++ ){
            int  m1 = read() , m2 = read() ;
            if( m1 == m2 )continue ;
            add( m1 , m2 ) , add( m2 , m1 ) ; 
        }
        dfs( 1 , 1 ) ; for( register int i = 1 ; i <= N ; ++i )vis[ i ] = false ; 
        int now = N ; vis[ now ] = true ;
        while( now != 1 )vis[ now ] = true , now = anc[ now ] ;
        for( register int i = 1 ; i <= N ; i++ )
            if( !dfn[ i ] ){
                root = i ; tarjan( i );  
            }
        int  ans = 0 ;
        for( register int i = 2 ; i < N ; i++ )
            if( cut[ i ] )ans++ ;
        printf("%d
    ",ans);
        for( register int i = 2 ; i < N ; i++ )
            if( cut[ i ]  ){
            	printf("%d ",i);cut[ i ] = 0 ;
            }
        printf("
    ") ;
        for( register int i = 1 ; i <= N ; ++i )
    	    vis[ i ] = dfn[ i ] = low[ i ] = head[ i ] = anc[ i ] = 0 ;
    	tot = 1 , num = 0 ;
    }
    int  main()
    {
        freopen("home.in","r",stdin);
        freopen("home.out","w",stdout);
        T = read() ; 
        while( T-- )work() ;
        return  0 ;
    }
    /*
    1
    5 5
    1 2
    2 3
    3 4
    4 5
    4 1
    */
    
  • 相关阅读:
    ZOJ 2859 Matrix Searching
    URAL 1102. Strange Dialog
    ZOJ 1986 Bridging Signals
    POJ 3233 Matrix Power Series
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    ZOJ 3471 Most Powerful
    IIS:HTTP 错误 403.9 禁止访问:连接的用户过多
    使用Command对象执行数据库操作
    C#类型转换
  • 原文地址:https://www.cnblogs.com/ssw02/p/11623321.html
Copyright © 2011-2022 走看看