• 《数据结构与算法分析:C语言描述》复习——第九章“图论”——割点


    2014.07.04 23:57

    简介:

      这本教材中提到了一个概念,叫关节点(articulation point)。如果从某个无向图里去掉某个顶点以及这个顶点所有的边,如果此时图中连通分量的个数增加了,那么定义这个顶点为“关节点”。更通俗地解释,可以说如果拿走这个顶点,这幅图就破成了好几块,因此这个点好比“关节”,没有了关节整个结构也就破坏掉了。

      后来上网搜了资料后,我才知道原来这就是割点。

    描述:

      解决这个问题的思路有以下几个线索:

        1. 选取一个节点执行深度优先搜索,逐渐生成一棵树。初始的那个顶点就是根节点。

        2. 如果根节点有至少2棵子树,那么根节点是割点(这个容易理解,如果拿走了根节点,就会出现多棵树)。

        3. 对于其他顶点v,如果v的所有子节点(不一定是直接相连的子节点)都不存在指向v的祖先的回路,那么v是割点(这个不太好理解,其实意思是说拿走了v以后,下面的子节点就无法连接到v以上的祖先节点了,这样图就断开了)。

      根据这三点思路,可以写出以下代码。

    实现:

      1 // My implementation for cut vertex detection on undirected graph.
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <vector>
      5 using namespace std;
      6 
      7 void findCutVertex(const vector<vector<bool> > &graph, int idx, const int n,
      8     int &counter, vector<int> &num, vector<int> &low, vector<int> &parent,
      9     vector<bool> &result)
     10 {
     11     int i;
     12     
     13     low[idx] = num[idx] = counter++;
     14     for (i = 0; i < n; ++i) {
     15         if (!graph[idx][i]) {
     16             continue;
     17         }
     18         
     19         if (num[i] < 0) {
     20             // Unvisited vertex
     21             parent[i] = idx;
     22             findCutVertex(graph, i, n, counter, num, low, parent, result);
     23             if (low[i] >= num[idx]) {
     24                 result[idx] = true;
     25             }
     26             low[idx] = min(low[idx], low[i]);
     27         } else if (parent[idx] != i) {
     28             // Visited vertex
     29             low[idx] = min(low[idx], num[i]);
     30         }
     31     }
     32 }
     33 
     34 void cutVertexDetection(const vector<vector<bool> > &graph, 
     35     vector<bool> &is_cut_vertex)
     36 {
     37     // Cut vertex detection for undirected graph.
     38     int n;
     39     
     40     n = (int)graph.size();
     41     is_cut_vertex.resize(n, false);
     42     
     43     if (n == 1) {
     44         is_cut_vertex[0] = true;
     45         return;
     46     }
     47     
     48     vector<int> parent;
     49     vector<int> num;
     50     vector<int> low;
     51     int counter;
     52     
     53     parent.resize(n, -1);
     54     num.resize(n, -1);
     55     low.resize(n, -1);
     56     counter = 0;
     57     findCutVertex(graph, 0, n, counter, num, low, parent, is_cut_vertex);
     58 
     59     // The root node must be checked separately.
     60     counter = 0;
     61     for (int i = 1; i < n; ++i) {
     62         if (parent[i] == 0) {
     63             ++counter;
     64         }
     65     }
     66     is_cut_vertex[0] = (counter > 1);
     67     
     68     parent.clear();
     69     num.clear();
     70     low.clear();
     71 }
     72 
     73 int main()
     74 {
     75     vector<vector<bool> > graph;
     76     vector<bool> is_cut_vertex;
     77     int n;
     78     int nk;
     79     int i, j;
     80     int tmp;
     81     
     82     while (cin >> n && n > 0) {
     83         graph.resize(n);
     84         for (i = 0; i < n; ++i) {
     85             graph[i].resize(n, false);
     86         }
     87         
     88         for (i = 0; i < n; ++i) {
     89             cin >> nk;
     90             for (j = 0; j < nk; ++j) {
     91                 cin >> tmp;
     92                 graph[i][tmp] = graph[tmp][i] = true;
     93             }
     94         }
     95         
     96         cutVertexDetection(graph, is_cut_vertex);
     97         cout << "The following vertices are cut vertices:" << endl;
     98         cout << '{';
     99         for (i = 0; i < n; ++i) {
    100             if (is_cut_vertex[i]) {
    101                 cout << i << ' ';
    102             }
    103         }
    104         cout << '}' << endl;
    105         
    106         for (i = 0; i < n; ++i) {
    107             graph[i].clear();
    108         }
    109         graph.clear();
    110         is_cut_vertex.clear();
    111     }
    112     
    113     return 0;
    114 }
  • 相关阅读:
    clickhouse使用docker安装单机版
    nacos使用docker安装单机版
    第三周学习进度
    第二周学习进度
    二柱子四则运算定制版
    课堂测试小程序
    学习进度
    阅读计划
    自我介绍
    寻找水王
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3825299.html
Copyright © 2020-2023  润新知