B - Network - uva 315(求割点)

题意:给一个无向连通图,求出割点的数量。
首先输入一个N(多实例,0结束),下面有不超过N行的数,每行的第一个数字代表后面的都和它存在边,0表示行输入的结束(很蛋疼的输入方式).
分析:割点的模板题
******************************************************************
#include<stdio.h>
#include< string.h>
#include<stack>
#include<algorithm>
using  namespace std;

const  int MAXN =  105;

struct Edge{ int v, next;}e[MAXN*MAXN];
int Head[MAXN], cnt;
void AddEgde( int u,  int v)
{
    e[cnt].v = v;
    e[cnt].next = Head[u];
    Head[u] = cnt++;
}

int f[MAXN], nRootSons; /// 记录父亲节点,和根节点的子树个数
int blsCutVetext[MAXN]; /// 是否属于割点
int Low[MAXN], Dfn[MAXN], Index; /// low保存深搜最早能够到达的点

void InIt( int N) /// 初始化
{
    cnt = nRootSons = Index =  0;
     for( int i= 0; i<=N; i++)
    {
        Head[i] = - 1;
        blsCutVetext[i] =  false;
        Dfn[i] =  false;
    }
}
void Tarjan( int u,  int father)
{
    f[u] = father;
    Low[u] = Dfn[u] = ++Index;

     for( int j=Head[u]; j!=- 1; j=e[j].next)
    {
         int v = e[j].v;
         if( !Dfn[v] )
        {
            Tarjan(v, u);
            Low[u] = min(Low[u], Low[v]);
        }
         else  if( v != father)
            Low[u] = min(Low[u], Dfn[v]);
    }
}

int main()
{
     int N;

     while(scanf( " %d ", &N), N)
    {
         int i, u, v;  char End;

        InIt(N);

         while(scanf( " %d ", &u), u)
        {
             while( 1)
            {
                scanf( " %d%c ", &v, &End);
                AddEgde(u, v);
                AddEgde(v, u);

                 if(End ==  ' \n ')
                     break;
            }
        }

        Tarjan( 10);

         for(i= 1; i<=N; i++)
        {
            u = f[i];
             if(u ==  1)
                nRootSons++;
             else  if( Dfn[u] <= Low[i] )
                blsCutVetext[u] =  true;
        }

         if(nRootSons >  1)
            blsCutVetext[ 1] =  true;

         int ans =  0;

         for(i= 1; i<=N; i++)
        {
             if(blsCutVetext[i] ==  true)
                ans++;
        }

        printf( " %d\n ", ans);
    }

     return  0;  

}

 

转载于:https://www.cnblogs.com/liuxin13/p/4691246.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值