zoukankan      html  css  js  c++  java
  • poj 1523(无向图求割点)

      1 /*
      2 构建一棵dfs树,序列dfn[i]为深度优先数,表示dfs时访问i节点的序号,low[i]表示从i节点出发能访问到的最小的深度优先数。
      3 
      4 当且仅当节点u满足如下两个条件之一时,u为割点:
      5 1.u为dfs树的根,且u至少有两个子节点。
      6 2.u不是dfs树的根,至少存在一个节点v是u的子节点,且low[v]>=dfn[u]。
      7 
      8 若u为割点,记subnets[u]为u的子节点数,则去掉u后,图被分成subnets[u]+1个部分(每个子节点的部分和u的祖先的部分),若u为dfs树的根,则分成subnets[u]个部分(根节点没有祖先)。
      9  */
     10 // File Name: 1523.cpp
     11 // Author: Missa
     12 // Created Time: 2013/4/24 星期三 13:53:18
     13 //O(n^2)
     14 #include<iostream>
     15 #include<cstdio>
     16 #include<cstring>
     17 #include<algorithm>
     18 #include<cmath>
     19 #include<queue>
     20 #include<stack>
     21 #include<string>
     22 #include<vector>
     23 #include<cstdlib>
     24 #include<map>
     25 #include<set>
     26 using namespace std;
     27 #define CL(x,v) memset(x,v,sizeof(x));
     28 #define R(i,st,en) for(int i=st;i<en;++i)
     29 #define LL long long
     30 
     31 const int inf = 0x3f3f3f3f;
     32 const int maxn = 1e3+5;
     33 vector <int> adj[maxn];
     34 bool vis[maxn];
     35 int n, tmpdfn, son, dfn[maxn], low[maxn], subnets[maxn];//顶点,当前dfn,儿子数,dfn,low,去掉此节点被分成的部分数
     36 void dfs(int u)
     37 {
     38     int size = adj[u].size();
     39     for (int i = 0; i < size; ++i)
     40     {
     41         int v = adj[u][i];
     42         if (!vis[v])
     43         {
     44             vis[v] = 1;
     45             tmpdfn ++;
     46             dfn[v] = low[v] = tmpdfn;
     47             dfs(v);
     48             low[u] = min(low[u], low[v]);
     49             if (low[v] >= dfn[u])
     50             {
     51                 if (u != 1) subnets[u] ++;//u的子节点数
     52                 //根结点的子女结点的个数(如果大于1,则根结点是关节点)
     53                 if (u == 1) son++;
     54             }
     55         }
     56         else  low[u] = min(low[u], dfn[v]);
     57     }
     58 }
     59 void init()
     60 {
     61     low[1] = dfn[1] = 1;
     62     tmpdfn = 1;
     63     son = 0;
     64     memset(vis, 0, sizeof(vis));
     65     vis[1] = 1;
     66     memset(subnets, 0, sizeof(subnets));
     67 }
     68 
     69 int main()
     70 {
     71     int u, v, flag, cas = 1;
     72     while(~scanf("%d",&u))
     73     {
     74         if (!u) break;
     75         init();
     76         memset(adj, 0, sizeof(adj));
     77         n = 0;
     78         scanf("%d", &v);
     79         adj[u].push_back(v);
     80         adj[v].push_back(u);
     81         n = max(u,v);
     82         while (~scanf("%d", &u))
     83         {
     84             if (!u) break;
     85             scanf("%d",&v);
     86             n = max(n, max(u,v));
     87             adj[u].push_back(v);
     88             adj[v].push_back(u);
     89         }
     90         if (cas != 1) printf("\n");
     91         printf("Network #%d\n", cas++);
     92         dfs(1);
     93         if (son > 1) subnets[1]  = son - 1;
     94         bool ok = 0;
     95         for (int i = 1; i <= n; ++i)
     96         {
     97             if (subnets[i])
     98             {
     99                 ok = 1;
    100                 printf("  SPF node %d leaves %d subnets\n",i, subnets[i] + 1);//u的子节点数+u的祖先
    101             }
    102         }
    103         if (!ok) printf("  No SPF nodes\n");
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    什么是Netflix Feign?它的优点是什么?
    Spring Boot 自动配置原理是什么?
    springcloud断路器作用?
    什么是SpringCloudConfig?
    find命令查找包含指定内容的文件
    @PostConstruct使用总结
    @Retention 注解的作用
    SpringBoot自定义Condition注解
    Spring Boot 入门
    SpringBoot +MSSQL
  • 原文地址:https://www.cnblogs.com/Missa/p/3040175.html
Copyright © 2011-2022 走看看