无向图连通性——割点

无向图连通性——割点

 

搜索方式为建立bfs搜索树,并更新dfn[ ]和low[ ]。与求强连通块类似,但割点u 的判断条件为:对于节点u 和他的子节点v,满足  low[v]>= dfn[u]。特别的,如果节点u 是搜索树的根节点,则u 是割点当且仅当搜索树上至少有两个子节点v1,v2 满足上述条件。

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<stack>
  6 using namespace std;
  7 const int maxv= 110;
  8 const int maxe= 5010;
  9 
 10 struct ENode
 11 {
 12     int to;
 13     int Next;
 14 };
 15 ENode edegs[maxe];
 16 int Head[maxv], tnt;
 17 void init()
 18 {
 19     memset(Head, -1, sizeof(Head));
 20     tnt= -1;
 21 }
 22 void Add_ENode (int a, int b)
 23 {
 24     ++ tnt;
 25     edegs[tnt].to= b;
 26     edegs[tnt].Next= Head[a];
 27     Head[a]= tnt;
 28     ++ tnt;
 29     edegs[tnt].to= a;
 30     edegs[tnt].Next= Head[b];
 31     Head[b]= tnt;
 32 }
 33 
 34 int dfn[maxv];  //深度优先搜索中顶点被访问的时间
 35 int low[maxv];  //顶点v 和它的邻接点中low[]的最小值
 36 int temp[maxv];  //判断节点是否已被访问过(0-未访问 1-已访问未删除 2-已访问已删除)
 37 int cut[maxv];  //判断点i 是否为割点
 38 int root;  //子树的根节点
 39 int tarjanbfs(int u, int &lay)
 40 {
 41     dfn[u]= ++ lay;
 42     low[u]=lay;
 43     int flag= 0;
 44     for (int k= Head[u]; k!= -1; k= edegs[k].Next)
 45     {
 46         int v= edegs[k].to;
 47         if (! dfn[v])
 48         {
 49             tarjanbfs(v, lay);
 50             low[u]= min(low[u], low[v]);
 51             if (low[v]>= dfn[u])
 52             {
 53                 flag ++;
 54                 if (u!= root|| flag> 1) cut[u]= 1;
 55             }
 56         }
 57         else
 58         {
 59             low[u]= min(low[u], dfn[v]);
 60         }
 61     }
 62 }
 63 
 64 void tarjan(int n)
 65 {
 66     int lay= 0;
 67     memset(low, 0, sizeof(low));
 68     memset(cut, 0, sizeof(cut));
 69     for (int i= 1; i<= n; i ++)
 70     {
 71         if (! dfn[i]) root= i, tarjanbfs(root, lay);
 72     }
 73 }
 74 
 75 int main()
 76 {
 77     int n, m;
 78     int x, y;
 79     while (~ scanf("%d %d", &n, &m))
 80     {
 81         init();
 82         for (int i= 0; i< m; i ++)
 83         {
 84             scanf("%d %d", &x, &y);
 85             Add_ENode(x, y);
 86         }
 87         tarjan(n);
 88 
 89         /**/
 90         for (int i = 1; i <= n; i++)
 91         {
 92             printf("%d%c", cut[i], i != n ? ' ' : '\n');
 93         }
 94         for (int i= 1; i<= n; i ++)
 95         {
 96             printf("%d%c", low[i], i != n ? ' ' : '\n');
 97         }
 98         for (int i= 1; i<= n; i ++)
 99         {
100             printf("%d%c", dfn[i], i != n ? ' ' : '\n');
101         }
102     }
103     return 0;
104 }
View Code

 

posted @ 2019-07-31 09:28  egoist的翻绳游戏  阅读(140)  评论(0编辑  收藏  举报