poj 1144 Network (无向图求割点)

来源:互联网 发布:魔戒 知乎 编辑:程序博客网 时间:2024/05/22 09:43
#include<iostream>#include<string.h>#include<vector>using namespace std;vector <int> vec[110];int dfn[110] , low[110],in[110];int n, step , sum ;void init(){   for(int i=0;i<110;i++)   {      dfn[i]=low[i]=in[i]=0;      vec[i].clear();   }   step=sum=0;}void insert(int u , int v){     vec[u].push_back(v);     vec[v].push_back(u);}void tarjan(int u , int rt ,int fa){    int v ,son=0;    low[u]=dfn[u]=++step;      for(int i=0;i<vec[u].size();i++)    {        v=vec[u][i];           if(!dfn[v])        {            son++;            tarjan(v , rt ,u);             low[u]=min(low[u] , low[v]);            if(u==rt && son>1 || low[v]>=dfn[u] && u!=rt ) in[u]=1;             //之前我的判断写成了low[v]>=low[u],改的我都快死了。         }        else  low[u]=min(low[u] , dfn[v]);     }}int main(){    int a, b;    while(scanf("%d",&n)!=EOF && n)    {        init();         while(scanf("%d",&a) && a)        {            while(getchar()!='\n')            {                scanf("%d",&b);                insert(a , b);            }        }        for(int i=1;i<=n;i++)        {             if(!dfn[i])                {                 tarjan(i ,i ,0);             }         }        for(int i=1;i<=n;i++)        if(in[i]) sum++;        printf("%d\n",sum);    }    return 0;}


之前一直有个盲点,多亏这道裸的求割点:  若该点是割点, 则去掉这个点后,整个图的连通分支一定会增多。例如:

3

1 2

2 3

这个图中1点就不是割点,另外环中的点也不是割点。

另外,这道题导致一直wa的原因,若判断失误,则在存在环(环中的点>=3)时一定会出问题。例如:

6

1 2

2 3

3 4

4 5

5 6

6 3    

这个图中递归到u=6时,停止递归 low[6] = 3 ,回到上一层 low[ 5 ] = min ( low[6]  ,  low[5] ) = 3 ,后面判断  low[v] > = low[u]一定存在,所以就会将环中的点也算作割点,导致错误。

原创粉丝点击