POJ1144 Network 题解 点双连通分量(求割点数量)
题目链接:http://poj.org/problem?id=1144
题目大意:给以一个无向图,求割点数量。
这道题目的输入和我们一般见到的不太一样。
它首先输入 \(N\)(\(\lt 100\))表示点的数量(\(N=0\)表示文件输入结束)。
然后接下来每行输入一组数字。
- 如果这一组数字只包含一个 \(0\) ,说明本组测试数据输入结束;
 - 否则,假设这些数可以拆分成 \(a_1,a_2,a_3, \cdots ,a_m\),则说明 \(a_1\) 这个点到 \(a_2,a_3, \cdots , a_m\) 之间都存在着一条边。
 
所以这道题目想要表达的意思还是一样的 \(\Rightarrow\) 求割点的数量,只不过输入方式和我们平时见到的不太一样。
观察DFS搜索树,我们可以发现有两类节点可以成为割点:
- 对根节点 \(u\) ,若其有两棵或两棵以上的子树,则该根结点 \(u\) 为割点;
 - 对非叶子节点 \(u\) (非根节点),若其子树的节点均没有指向 \(u\) 的祖先节点的回边,说明删除 \(u\) 之后,根结点与 \(u\) 的子树的节点不再连通,有 \(low[v] \ge dfn[u]\) ;则节点 \(u\) 为割点。
 
实现代码如下:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn = 10010;
int n, m, dfn[maxn], low[maxn], f[maxn], cnt, ans;
bool vis[maxn];
vector<int> g[maxn];
void init() {
    ans = cnt = 0;
    for (int i = 1; i <= n; i ++) {
        low[i] = dfn[i] = f[i] = vis[i] = 0;
        g[i].clear();
    }
}
void tarjan(int u) {
    low[u] = dfn[u] = ++cnt;
    int son_num = 0;    // 记录子树数量
    int sz = g[u].size();
    for (int i = 0; i < sz; i ++) {
        int v = g[u][i];
        if (!dfn[v]) {  // v未被访问,(u,v)为树边
            son_num ++;
            f[v] = u;
            tarjan(v);
            low[u] = min(low[u], low[v]);
            if (dfn[u] == 1 && son_num > 1 && !vis[u]) {    // 根节点,子树数量大于1即为割点
                vis[u] = true;
                ans ++;
            }
            else if (dfn[u] != 1 && low[v] >= dfn[u] && !vis[u]) {  // 其余节点子树可追溯到最早的祖先节点要么为v要么为u
                vis[u] = true;
                ans ++;
            }
        }
        else if (f[v] != u) {   // 节点v已被访问,则(u,v)为回边
            low[u] = min(low[u], dfn[v]);
        }
    }
}
int main() {
    while (~scanf("%d", &n) && n) {
        init();
        getchar();
        string s;
        int a, b;
        while (getline(cin, s)) {
            stringstream ss(s);
            ss >> a;
            if (!a) break;
            while ((ss >> b) && b) {
                g[a].push_back(b);
                g[b].push_back(a);
            }
        }
        tarjan(1);
        cout << ans << endl;
    }
    return 0;
}
参考链接:
POJ1144 Network 题解 点双连通分量(求割点数量)的更多相关文章
- POJ1144:Network(无向连通图求割点)
		
题目:http://poj.org/problem?id=1144 求割点.判断一个点是否是割点有两种判断情况: 如果u为割点,当且仅当满足下面的1条 1.如果u为树根,那么u必须有多于1棵子树 2. ...
 - poj 1144 Network【双连通分量求割点总数】
		
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11042 Accepted: 5100 Descript ...
 - C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建
		
最近在学图论相关的内容,阅读这篇博客的前提是你已经基本了解了Tarjan求点双. 由割点的定义(删去这个点就可使这个图不连通)我们可以知道,坍塌的挖煤点只有在割点上才会使这个图不连通,而除了割点的其他 ...
 - POJ 1144 Network(无向图连通分量求割点)
		
题目地址:id=1144">POJ 1144 求割点.推断一个点是否是割点有两种推断情况: 假设u为割点,当且仅当满足以下的1条 1.假设u为树根,那么u必须有多于1棵子树 2.假设u ...
 - hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】
		
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Su ...
 - zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】
		
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...
 - 【HDU4612】 双连通分量求桥
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 题目大意:给你一个无向图,问你加一条边后最少还剩下多少多少割边. 解题思路:好水的一道模板题.先 ...
 - POJ3694 Network(边双连通分量+缩点+LCA)
		
题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...
 - fzu2181(点的双连通分量+求奇环)
		
求出每个点双连通分量,如果在一个点双连通分量中有奇环,则这个分量每个点都在一个奇环中. 关键是要知道怎么求点双连通分量以及点双连通的性质. fzu2181 http://acm.fzu.edu.cn ...
 
随机推荐
- Python深入:02浅拷贝深拷贝
			
对象赋值实际上是简单的对象引用.也就是说当你创建一个对象,然后把它赋给另一个变量的时候,Python并没有拷贝这个对象,而只是拷贝了这个对象的引用. 假设想创建一对小夫妻的通用档案,名为person. ...
 - @codechef - BIKE@ Chef and Bike
			
目录 @description@ @solution@ @accepted code@ @details@ @description@ 输入 n(n ≤ 22) 个点,m(m ≤ 8000) 个边.每 ...
 - H3C RARP
 - [C#] WebClient性能优化
			
WebClient缺省是为了安全和方便,不是为了性能.所以,当你打算做压力测试的时候,就会发现WebClient很慢. WebClient性能很差,主要原因有: 1.它缺省会使用IE的代理设置,而IE ...
 - 使用colab平台进行训练
			
https://www.zhongxiaoping.cn/2018/12/01/%E4%BD%BF%E7%94%A8colab%E5%B9%B3%E5%8F%B0%E8%BF%9B%E8%A1%8C% ...
 - Python--day69--ORM的F查询和Q查询
			
F查询和Q查询 F查询 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较.如果我们要对两个字段的值做比较,那该怎么做呢? Django 提供 F() 来做这样的比较.F() 的实例可 ...
 - 关于 FormData 和 URLSearchParams
			
一.FormData FormData 接口提供了一种表示表单数据的键值对的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出,本接口和此方法都相当简单直接.如果送出 ...
 - [转]java常用正则表达式
			
只能输入数字:"^[0-9]*$". 只能输入n位的数字:"^\d{n}$". 只能输入至少n位的数字:"^\d{n,}$". 只能输 ...
 - java 利用TCP上传文件
			
从客户端上传到服务器端,其实本质上也就是复制! package july76net; //上传文件(文本) import java.io.BufferedReader; import java.io. ...
 - 2018-2-13-C#-通配符转正则
			
title author date CreateTime categories C# 通配符转正则 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23:3 ...