[POJ1144]题面翻译-割点裸题

说在前面

其实me博客里有一篇文章把割点桥,强连通双连通的板子都总结了一遍。这道题…核心算法直接贴板子就可以过了的。
本来没有写这个题解的打算,然而真是服了这谜一样的题面和读入方式,最终me决定还是写一点什么,比如题面的翻译和输入解释….


题面

POJ1144传送门

题意

给你一张图,节点数小于100个,保证图联通。询问这张图里有多少割点

输入

多组测试数据
对于每组测试数据的第一行,输入一个整数N,表示一共有N个节点
接下来若干行,每行第一个数字u,接下来一些数字vi,表示u和vi之间有边,每行以回车符结尾。
每组测试数据以u==0结尾
整个输入以N==0结尾

输出

每组测试数据一行,表示割点个数


题解

这题,数据规模小到一定境界(毕竟是96年的题),随便乱搞都可以。
最暴力的做法比如:直接枚举每个点是不是割点。
正常一点的做法比如:tarjan求割点。
看个人喜好。直接上代码吧。


自带大常数的代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

int N , head[105] , tp , cnt ;
class Path{
    public :
        int pre , to ;
}p[100005] ;

void In( int t1 , int t2 ){
    p[++tp].pre = head[t1] ;
    p[ head[t1] = tp ].to = t2 ;
}

int dfn[105] , dfs_c ;
bool iscut[105] ;
int dfs( int u , int f ){
    int lowu = dfn[u] = ++dfs_c , child = 0 ;
    for( int i = head[u] ; i ; i = p[i].pre ){
        int v = p[i].to ;
        if( v == f ) continue ;
        if( !dfn[v] ){
            child ++ ;
            int lowv = dfs( v , u ) ;
            lowu = min( lowv , lowu ) ;
            if( lowv >= dfn[u] )
                iscut[u] = true ;
        } else lowu = min( dfn[v] , lowu ) ;
    }
    if( f == -1 && child == 1 ) iscut[u] = false ;
    return lowu ;
}


void clear(){
    cnt = dfs_c = tp = 0 ;
    memset( dfn , 0 , sizeof( dfn ) ) ;
    memset( head , 0 , sizeof( head ) ) ;
    memset( iscut , 0 , sizeof( iscut ) ) ;
}

int main(){
    int u , v ;
    while( scanf( "%d" , &N ) && N ){
        clear() ;
        while( scanf( "%d" , &u ) && u ){
            while( 1 ){
                scanf( "%d" , &v ) ;
                In( u , v ) ;
                In( v , u ) ;
                if( getchar() == '\n' ) break ;
            }
        }
        dfs( 1 , -1 ) ;
        for( int i = 1 ; i <= N ; i ++ )
            if( iscut[i] ) cnt ++ ;
        printf( "%d\n" , cnt ) ;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值