题目链接:http://poj.org/problem?id=1144

描述
一个电话线公司(简称TLC)正在建立一个新的电话线缆网络。他们连接了若干个地点分别从1到N编号。没有两个地点有相同的号码。这些线是双向的并且能使两个地点保持通讯。每个地点的线都终结于电话交换机。每个地点都有一个电话交换机。从每个地点都能通过线缆到达其他任意的地点,然而它并不需要直接连接,它可以通过若干个交换机来到达目的地。有时候某个地点供电出问题时,交换机就会停止工作。TLC的工作人员意识到,除非这个地点是不可达的,否则这种情况就会发生,它还会导致一些其它的地点不能互相通讯。在这种情况下我们会称这个地点(错误发生的地方)为critical。现在工作人员想要写一个程序找到所有critical地点的数量。帮帮他们。
输入
输入文件包括若组测试数据。每一组是一个网络,每一组测试数据的第一行是地点的总数量N<100. 每个接下来最多N行包括一个数字表示一个地点和与它相连接的地点的数字。这些最多N行完全描述了整个网络,比如,网络中每个直接连接的两个地点被至少一行包括。一行内的所有数字都要用空格隔开。每组数据需要用单独的一个0结束。最后的块只有一行即N=0。
输出
输出除了最后一个组其他每一个组的critical地点的数量,每个块用一行输出。
样例输入:
5
5 1 2 3 4
0
6
2 1 3
5 4 6 2
0
0
样例输出
1
2
提示:
你需要确定每行的结束。为了方便判断,每行的结束都没有多余的空白
 
解题思路:求无向图割点的数量
简单介绍下tarjan算法求割点的原理:

观察DFS搜索树,我们可以发现有两类节点可以成为割点:

  1. 对根节点u,若其有两棵或两棵以上的子树,则该根结点u为割点;
  2. 对非叶子节点u(非根节点),若其子树的节点均没有指向u的祖先节点的回边,说明删除u之后,根结点与u的子树的节点不再连通,有low[v]>=dfn[u];则节点u为割点。

代码:

#include<iostream>
#include<vector>
#include<cstdio>
#include<string>
#include<sstream>
using namespace std;
typedef long long ll;
const int maxn=;
vector<int> mp[maxn];
int n,m,ans,low[maxn],dfn[maxn],par[maxn],ap[maxn],cnt;
void init(){
ans=;
cnt=;
for(int i=;i<=n;i++){
low[i]=dfn[i]=;
par[i]=;
ap[i]=;
mp[i].clear();
}
}
void tarjan(int u){
dfn[u]=low[u]=++cnt; //cnt记录遍历次序
int son=; //记录子树数量
for(int i=;i<mp[u].size();i++){
int v=mp[u][i];
if(!dfn[v]){ //v未被访问,(u,v)为树边
son++;
//记录v的父亲节点
par[v]=u;
tarjan(v);
low[u]=min(low[u],low[v]);
//根节点,子树数量大于1即为割点
if(dfn[u]==&&son>&&!ap[u])
ap[u]=,ans++;
//其余节点子树可追溯到最早的祖先节点要么为v要么为u
else if(dfn[u]!=&&low[v]>=dfn[u]&&!ap[u])
ap[u]=,ans++;
}
else if(par[v]!=u) //节点v已被访问,则(u,v)为回边
low[u]=min(low[u],dfn[v]);
}
}
int main(){
int a,b;
string s;
while(~scanf("%d",&n)&&n){
init();
getchar();
while(){
getline(cin,s);
stringstream ss(s);
ss>>a;
if(!a)break;
while(ss>>b&&b){
mp[a].push_back(b);
mp[b].push_back(a);
}
}
tarjan();
cout<<ans<<endl;
}
return ;
}

poj 1144 (Tarjan求割点数量)的更多相关文章

  1. POJ 1144 无向图求割点

     学长写的: #include<cstdio>#include<cstdlib>#include<cmath>#include<iostream>#in ...

  2. POJ 1523 Tarjan求割点

    SPF Description Consider the two networks shown below. Assuming that data moves around these network ...

  3. POJ 1144 Network(Tarjan求割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12707   Accepted: 5835 Descript ...

  4. poj 1523 SPF(tarjan求割点)

    本文出自   http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...

  5. POJ1144 Network 题解 点双连通分量(求割点数量)

    题目链接:http://poj.org/problem?id=1144 题目大意:给以一个无向图,求割点数量. 这道题目的输入和我们一般见到的不太一样. 它首先输入 \(N\)(\(\lt 100\) ...

  6. Tarjan求割点和桥

    by szTom 前置知识 邻接表存储及遍历图 tarjan求强连通分量 割点 割点的定义 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多, ...

  7. tarjan求割点与割边

    tarjan求割点与割边 洛谷P3388 [模板]割点(割顶) 割点 解题思路: 求割点和割点数量模版,对于(u,v)如果low[v]>=dfn[u]那么u为割点,特判根结点,若根结点子树有超过 ...

  8. UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数

    Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...

  9. poj_1144Network(tarjan求割点)

    poj_1144Network(tarjan求割点) 标签: tarjan 割点割边模板 题目链接 Network Time Limit: 1000MS Memory Limit: 10000K To ...

随机推荐

  1. JQuery动态修改样式

    JQuery动态修改样式 SetStyle(); function SetStyle() { $(".toolbar").remove(); $(".placeholde ...

  2. C# 父子页面传值

    业务需求是:父页面点击“选择任务”按钮进入任务列表页.(项目进度周报) 父页面如下: 任务列表页: 选择某一个任务,点击“确定”后返回父页面所需数据. 父页面“选择任务” 按钮触发事件. /// &l ...

  3. [转帖]SAP一句话入门:Finacial & Controlling Accounting

    SAP一句话入门:Finacial & Controlling Accounting http://blog.vsharing.com/MilesForce/A621147.html 财务,财 ...

  4. 腾讯机试题 AcWing 603 打怪兽

    题目链接:https://www.acwing.com/problem/content/605/ 题目大意: 略 分析: 用dp[i][j]表示用j元钱能在前i只怪兽上所能贿赂到的最大武力值. 有一种 ...

  5. java内部类 和外部类的区别

    java 内部类和静态内部类的区别  详细连接https://www.cnblogs.com/aademeng/articles/6192954.html 下面说一说内部类(Inner Class)和 ...

  6. java中级——集合框架【4】-Collections

    Collections 首先我们要知道Collections是一个类,容器的工具类,就如同Arrays是数组的工具类 反转 reverse 使List中的数据发生发转 package cn.jse.c ...

  7. jvm相关参数

    官方地址:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html#BEHHGFAE 一.查看jvm运行参数 1.查看 ...

  8. easyui 自动动态合并单元格

    .......onLoadSuccess : function(data) { if (data.rows.length > 0) { //调用mergeCellsByField()合并单元格 ...

  9. git bash 下操作文件及文件夹命令

    1, cd : change directory的简写,改变目录的意思,就是切换到哪个目录下, 如 cd e:\fff  切换 E 盘下面的fff 目录. 当我们用cd 进入文件夹时,我们可以使用 通 ...

  10. Linux下git的使用——将已有项目放到github上

    本地已经有一个项目了,需要将该项目放到github上,怎么操作? 步骤: 本地安装git,有github账号是前提. (1)先在github创建一个空的仓库,并复制链接地址.使用https,以.git ...