• POJ 3713 Transferring Sylla【Tarjan求割点】


    题意:给出一个无向图,判断是否任意两点间都存在至少3条互相独立的路,独立指公共顶点只有起点和终点。
    算法:枚举每个点,删去后用Tarjan判断图中是否存在割点,如果存在则该图不满足三连通性。Tarjan中保存搜索树,多子树的根节点为割点;
    dfs顺序为节点编号,dp得到每个子树通过回边能回到的最小编号,若某点的子树们能回到的点大于等于自己,则该点为割点。
    转自:yogykwan
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 int del, root;
     9 bool cut;
    10 int dfn[510], low[510];
    11 
    12 vector<int> e[510];
    13 int n, m;
    14 int tot;
    15 
    16 void Tarjan(int u, int p) { // 当前节点,父亲节点
    17     if (cut) return;
    18     dfn[u] = low[u] = ++tot;
    19     int son = 0;
    20     for (vector<int>::iterator it = e[u].begin(); it != e[u].end(); ++it) {
    21         int v = *it;
    22         if (v == p || v == del) continue;
    23         if (!dfn[v]) {
    24             ++son;
    25             Tarjan(v, u);
    26             low[u] = min(low[u], low[v]);
    27             if ((u == root && son > 1) || (u != root && low[v] >= dfn[u])) { // 割点条件
    28                 cut = 1;
    29                 return;
    30             }
    31         } else {
    32             low[u] = min(low[u], dfn[v]);
    33         }
    34     }
    35 
    36 }
    37 
    38 int main() {
    39     while (scanf("%d%d", &n, &m) != EOF && n) {
    40         for (int i = 0; i < n; ++i) e[i].clear();
    41         for (int i = 0; i < m; ++i) {
    42             int u, v;
    43             scanf("%d%d", &u, &v);
    44             e[u].push_back(v);
    45             e[v].push_back(u);
    46         }
    47         cut = 0;
    48         for (int i = 0; i < n; ++i) {
    49             del = i;
    50             memset(dfn, 0, sizeof(dfn));
    51             tot = 0;
    52             root = !i;
    53 
    54             Tarjan(root, -1);
    55             if (cut) break;
    56             for (int j = 0; j < n; ++j) {
    57                 if (j != del && !dfn[j]) {  // 不是连通图
    58                     cut = 1;
    59                     break;
    60                 }
    61             }
    62             if (cut) break;
    63         }
    64         printf("%s
    ", cut ? "NO" : "YES");
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    JS-鼠标经过显示二级菜单
    CSS-论css如何纯代码实现内凹圆角
    JS-制作可伸缩的水平菜单栏
    CSS-混合布局的几种方法(正确的方法和错误的原因)
    JS-选项卡制作解释部分
    JS-制作网页特效——选项卡效果(水平,点击)
    JS-DOM 综合练习-动态添加删除班级成绩表
    JS-DOM对象知识点汇总(慕课)
    JS-window对象集合
    JS-节点属性(常用!)
  • 原文地址:https://www.cnblogs.com/demian/p/9222257.html
Copyright © 2020-2023  润新知