hrbustoj 1494(原题UVA 315 Network) 解题报告 tarjan求割点

  主要思路:使用tarjan选取一个根节点建立一个棵搜索树,判断一个点是割点的充分必要条件是,对于一个节点u如果他的孩子节点v的low值大于等于u的出生日期dfn值,进行下一步判断,如果u是我们选的根节点,我们还需要判断一下他的孩子节点的个数是否大于一,如果大于一则他是割点,反之不是。如果u不是根节点,那他就是割点了。因为我是第一次接触targin算法,跟着学姐的课件和自己的感觉敲了下去,WA已经刷屏了,原因就是我错误的认为根节点只要度数大于一就可以(学姐课件上就是先写的这个啊T T),其实是他也必须要满足low >= dfn的关系。。。好吧,以后记住就可以了^ ^.

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int maps[110][110],dfn[110],low[110],tot,n,root_son,mark[110],flag[110];
char a[300];
void tarjan(int u,int fa)
{
    for(int i = 1; i <= n; i++)
    {
        if(maps[u][i])
        {
            ///cout<<"the fa = "<<u<<"  the son is = "<<i<<endl;
            if(!flag[i])
            {
                flag[i] = 1;
               /// cout<<"the son "<<i<<" is not visited
";
                dfn[i] = low[i] = ++tot;
                tarjan(i,u);
                low[u] = min(low[i],low[u]);
                if(low[i] >= dfn[u])
                {
                    if(u != 1) mark[u] = 1;
                    else root_son++;
                }
            }
            else if(i != fa)
            {
                ///cout<<"the son "<<i<<" is visited"<<endl;
                low[u] = min(low[u],dfn[i]);
              /// cout<<"low["<<u<<"]"<<" hes become "<<low[u]<<endl;
            }
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d",&n) && n)
    {
        getchar();
        memset(maps,0,sizeof(maps));
        while(gets(a))
        {
            if(a[0] == '0') break;
            int len = strlen(a);
            a[len] = ' ';
            a[len+1] = '';
            int pos = 0,num,c,fi,flag = 0;
            for(int i = 0; i <= len; i++)
            {
                if(a[i] == ' ')
                {
                    num = 0,c = 1;
                    for(int j = i-1; j >= pos; j--)
                    {
                        num += c * (a[j] - '0');
                        c *= 10;
                    }
                    pos = i+1;
                    //cout<<"num = "<<num<<endl;
                    if(!flag)
                    {
                        fi = num;
                        flag = 1;
                    }
                    else
                    {
                        maps[fi][num] = 1;
                        maps[num][fi] = 1;
                    }
                }
            }
        }
        memset(a,0,sizeof(a));
        tot = 1;
        memset(flag,0,sizeof(flag));
        flag[1] = low[1] = dfn[1] = 1;
        root_son = 0;
        memset(mark,0,sizeof(mark));
        //cout<<"dfs = "<<endl;
        tarjan(1,-1);
       /*for(int i = 1; i <= n; i++)
        {
            cout<<dfn[i]<<"  "<<low[i]<<endl;
        }*/
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            if(mark[i]) ans++;
        }
        if(root_son >= 2) ans++;
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jifahu/p/5503004.html