• 割点算法


    要判定一个结点u是不是割点的方法是

    dfs树中

    ①u是根结点,如果u有两个及其以上的孩子(因为是dfs,所以如果有两个孩子,那么这两个孩子只通过u连接到一起),那么u是割点

    ②u不是根结点,如果u的后代的时间戳能够比u的时间戳小,即u的后代有边能够连回u的祖先,那么u不是割点(即low[v] < pre[u]),反之,u是割点(即low[v] >= pre[u])

    定义pre[u] 为结点u搜索的次序编号(时间戳)
    low[u]为u或者u的子树能够访问到的最小次序号,
    low[u] = min
    { 
    pre[u],
    pre[v], (u,v)为后向边
    low[v] (u,v)为树枝边,u为v的父亲
    }

    poj 1523

    题意:如果某个点是割点,求删除该点后,将图分成了几个联通块。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 using namespace std;
     5 
     6 const int N = 1000 + 10;
     7 vector<int> G[N];
     8 int pre[N],iscut[N],dfs_clock;
     9 int max(const int &a, const int &b)
    10 {
    11     return a > b ? a : b;
    12 }
    13 int min(const int &a, const int &b)
    14 {
    15     return a < b ? a : b;
    16 }
    17 
    18 int dfs(int u, int fa)
    19 {
    20     int lowu = pre[u] = ++dfs_clock;
    21     int child = 0;
    22     for(int i=0; i<G[u].size(); ++i)
    23     {
    24         int v = G[u][i];
    25         if(!pre[v])
    26         {
    27             child ++;
    28             int lowv = dfs(v,u);
    29             lowu = min(lowu,lowv);
    30             if(lowv >= pre[u])
    31                 iscut[u]++;//找出结点u有多少个孩子不能连回自己的祖先,如果是找割点,那么iscut[u] = ture;即可
    32         }
    33         else if(v!=fa && pre[v] < pre[u])//v!=fa说明不能是反向边,而是后向边
    34             lowu = min(lowu,pre[v]);
    35     }
    36     if(fa<0 && child>=1) iscut[u] = child-1;//dfs树,根结点的特判
    37     return lowu;
    38 }
    39 int main()
    40 {
    41     int a,b,n,i;
    42     int tCase = 1;
    43     while(true)
    44     {
    45         for(i=0; i<N; ++i)
    46         {
    47             pre[i] = iscut[i] = 0;
    48             G[i].clear();
    49         }    
    50         dfs_clock = 0;
    51         scanf("%d",&a);
    52         if(a==0)
    53             break;
    54         scanf("%d",&b);
    55         n = max(a,b);
    56         G[a].push_back(b);
    57         G[b].push_back(a);
    58         while(true)
    59         {
    60             scanf("%d",&a);
    61             if(a==0)
    62                 break;
    63             scanf("%d",&b);
    64             n = max(n,a);
    65             n = max(n,b);
    66             G[a].push_back(b);
    67             G[b].push_back(a);
    68         }
    69         if(tCase > 1)
    70             puts("");
    71         dfs(1,-1);
    72         printf("Network #%d
    ",tCase++);
    73         bool find = false;
    74         for(i=1; i<=n; ++i)
    75         {
    76             if(iscut[i] != 0)
    77             {
    78                 find = true;
    79                 printf("  SPF node %d leaves %d subnets
    ",i,iscut[i]+1);
    80             }
    81         }
    82         if(!find)
    83             puts("  No SPF nodes");
    84 
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    Sitecore 9 介绍
    Sitecore个性化
    Sitecore个性化
    Sitecore A / B测试
    Sitecore性化
    cesium结合geoserver利用WFS服务实现图层编辑(附源码下载)
    leaflet地图全图以及框选截图导出功能(附源码下载)
    openlayers6结合geoserver利用WFS服务实现图层编辑功能(附源码下载)
    arcgis api 4.x for js扩展MapImageLayer支持图片图层加载
    cesium结合geoserver利用WFS服务实现图层删除(附源码下载)
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4110777.html
Copyright © 2020-2023  润新知