题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=122091#problem/B

 

题意: :有n个电话,有一些线连接在他们之间,有的电话如果不能工作了,则可能导致n个电话不连通了,求出这样的电话又几个,其实就是求割点有多少个

 

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 10005
vector<vector<int> > G;

int father[maxn], low[maxn], dfn[maxn], cut[maxn];
int times, n;

void Init()
{
    G.clear();
    G.resize(n+5);
    memset(father, 0, sizeof(father));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    memset(cut, 0, sizeof(cut));
    times = 0;
}

void Tarjan(int u, int fa)
{
    low[u] = dfn[u] = ++times;
    father[u] = fa;

    int len = G[u].size(),v;

    for(int i=0; i<len; i++)
    {
        v = G[u][i];
        if(!dfn[v])
        {
            Tarjan(v, u);

            low[u] = min(low[u], low[v]);
        }
        else if(fa != v)
            low[u] = min(low[u], dfn[v]);
    }
}

int solve()
{
    int bs=0, ans=0, v;

     Tarjan(1, 0);

     for(int i=2; i<=n; i++)
     {
         v = father[i];
         if(v == 1)
            bs ++;
         else if(dfn[v] <= low[i])
            cut[v] = 1;
     }
     for(int i=2; i<=n; i++)
     {
         if(cut[i])
            ans++;
     }
      if(bs > 1) ans++;
     return ans;
}
int main()
{
     while(scanf("%d", &n),n)
     {
         int a, b;
         char ch;
         Init();

         while(scanf("%d", &a), a)
         {
             while(scanf("%d%c",&b, &ch))
             {
                 G[a].push_back(b);
                 G[b].push_back(a);
                 if(ch == '\n')
                    break;
             }
         }

        printf("%d\n", solve());
     }
    return 0;
}
View Code

 

posted on 2016-07-14 18:01  不忧尘世不忧心  阅读(111)  评论(0编辑  收藏  举报