zoukankan      html  css  js  c++  java
  • POJ1144Network(求割点个数)

    题目链接

    题意:一共n割点,然后若干行,每行第一个输入一个点,然后若干个点表示与他相连,0单独一行表示一个样例的结束。然后求图中的割点个数

    割点:去掉该点之后得到的图不在连通,那么该店就是割点

    一般割点有两种情况:1、父节点,当有两个或两个以上儿子节点的时候 2、dfn[x]表示深搜是x点是第几个开始搜索的,low[x]表示x及其父节点所能指向的最早的祖先,这个边官方就做回边,也就是回边往上能最高能到哪。如果 low[x] >= dfn[x] 也就是说x他的儿子们最多到x甚至还在x的下面,所以x就是割点,去掉x时候,x的儿子们就和x的上面的祖先们失去了联系

    然后就是对low[u]的更新:普通情况下,就是u->v,然后v没有没访问,所以low[u] = min( low[u], low[v]) 另一中情况就是回边的情况,u->v然而v已经访问完了,说明v在上面,u是下面的,u是指向祖先的。此时 low[u] = min( low[u], dfn[v]);

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 using namespace std;
     7 const int Max = 105;
     8 vector<int> g[Max];
     9 int vis[Max],low[Max],pre[Max],iscut[Max];
    10 int n,root,time;
    11 int get_min(int x, int y)
    12 {
    13     if(x > y)
    14         return y;
    15     return x;
    16 }
    17 void dfs(int u)
    18 {
    19     int child = 0;
    20     pre[u] = low[u] = ++time;
    21     vis[u] = 1;
    22     int len = g[u].size();
    23     for(int i = 0; i < len; i++)
    24     {
    25         int w = g[u][i];
    26         if(!vis[w])
    27         {
    28             child++;
    29             dfs(w);
    30             low[u] = get_min(low[u], low[w]);
    31             if(u == root && child == 2)  //根节点如果有两个以上儿子节点就是割点
    32                 iscut[u] = 1;
    33             if(u != root && low[w] >= pre[u]) //u的子孙节点如果指向的最早节点还比u要大的话,u也是割点
    34                 iscut[u] = 1;
    35         }
    36         else if(w != u)  // 这是应该避免重点的情况吗?
    37             low[u] = get_min(low[u], pre[w]);
    38     }
    39 }
    40 int main()
    41 {
    42     while (scanf("%d", &n) != EOF && n)
    43     {
    44         int a, b;
    45         for(int i = 0; i <= n; i++)
    46             g[i].clear();
    47         while(scanf("%d", &a) && a)
    48         {
    49             char ch;
    50             while ( (ch = getchar()) != '
    ')
    51             {
    52                 scanf("%d", &b);
    53                 g[a].push_back(b);
    54                 g[b].push_back(a);
    55             }
    56         }
    57         memset(pre, 0, sizeof(pre));
    58         memset(vis, 0, sizeof(vis));
    59         memset(low, 0, sizeof(low));
    60         memset(iscut, 0, sizeof(iscut));
    61         time = 0;
    62         root = 1;
    63         dfs(1);
    64         int ans = 0;
    65         for(int i = 1; i <= n; i++)
    66             if(iscut[i])
    67                 ans++;
    68         printf("%d
    ", ans);
    69     }
    70 }
    View Code
  • 相关阅读:
    课时8:环绕通知
    课时7:后置通知、异常通知
    课时6::AOP、execution表达式、前置通知
    课时:5 使用注解实现声明式事务
    课时22::PageHelper分页插件
    课时21 :使用MyBatis实现批量操作
    课时4:特殊值的注入问题和各种类型的自动装配
    课时3:三种方式的依赖注入、给各种集合类型的属性注入
    课时2:解耦合发展史、控制反转、依赖注入
    课时1:Spring环境搭建、STS工具、第一个Spring程序
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5279735.html
Copyright © 2011-2022 走看看