题目链接: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;
}

参考链接:

最新文章

  1. linux 遇见的问题
  2. 2.多线程-GCD
  3. 解决 主界面mainactivity 中fragment弹框把下面tab选项卡 顶上去的方案
  4. Robot Framework--安装篇
  5. iOS 简单提示view
  6. TortoiseGit GitHub 使用指南
  7. C#操作文件
  8. Codeforces 435 A Queue on Bus Stop
  9. cocoaPods第三方库使用详解
  10. 【Hexo】Hexo+Github构建个人博客 (三):添加皮肤主题
  11. Android JNI so库的开发
  12. Redis数据类型List
  13. Confluence 6 上传站点图标后重置你的配色方案
  14. Codeforces gym 101343 A. On The Way to Lucky Plaza【概率+逆元+精度问题】
  15. BZOJ2794[Poi2012]Cloakroom——离线+背包
  16. Java中的国际化
  17. hibernate 验证异常 javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint
  18. Iterm2的一些好用法
  19. cordforce 495 补题 &lt;未完&gt;
  20. [yii]Trying to get property of non-object

热门文章

  1. @atcoder - ARC066F@ Contest with Drinks Hard
  2. 非常优秀的Javascript(AJAX) 开发工具:Aptana
  3. HDU 4417 Super Mario 主席树查询区间小于某个值的个数
  4. poj 3675 Telescope (圆与多边形面积交)
  5. 【DCN】路由操作
  6. Python--day70--ORM多对多的三种方式
  7. CRF(条件随机场)与Viterbi(维特比)算法原理详解
  8. springmvc web.xml和application.xml配置详情(附:完整版pom.xml)
  9. 4-2 setting中一定要将ROBOTSTXT_OBEY = False的注释去掉
  10. H3C 显示RIP当前运行状态及配置信息