POJ 1523 SPF (割点,连通分量)
题意:给出一个网络(不一定连通),求所有的割点,以及割点可以切分出多少个连通分量。
思路:很多种情况。
(1)如果给的图已经不是连通图,直接“ No SPF nodes”。
(2)求所有割点应该不难,就是tarjan发明的算法搞定。但是求连通分量就得小心了,多种情况。看下:
1)如果一个割点x,其所有孩子都不是割点,那么x至少可以割出两个连通分量(x之上和之下的各1个)。
2)如果一个割点x,其有部分孩子是割点,有部分孩子并不是割点,那么x可以割出x之上的1个连通分量,不是割点的孩子均是同1个连通分量,是割点的孩子各自分别是一个连通分量。
3)如果一个割点x,如果有些孩子是叶子节点,且该叶子节点的度为1,即连着x,那么该叶子节点会被割出来,单点也是连通分量。
//#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <climits>
using namespace std;
const int N=;
int mapp[N][N];
int cntr, flag, up; //时间戳
int dfn[N], low[N], vis[N], iscut[N], cur[N]; //记录时间戳, 反边最顶点, 访问记录, 是否连通分量 bool DFS(int x, int far)
{
int chd=; //孩子节点个数
int cnt=, sum=;
dfn[x]=low[x]=++cntr; //时间戳
vis[x]=; //DFS必备
for(int i=; i<=up; i++)
{
if(!mapp[i][x]) continue;
if(!vis[i]) //树边
{
chd++;
bool f=DFS(i,x); //i点只有一条边
low[x]=min(low[x],low[i]); //判断连通分量的个数
if(!far && chd> || far && low[i]>=dfn[x] ) //能让x成为割点的孩子i
{ sum++;
iscut[x]=;
if(iscut[i]||f) cnt++; //这个孩子是割点或者满足单点单边条件
}
}
else if(i!=far)
low[x]=min(low[x], dfn[i]);
}
if(!far && iscut[x])
{
iscut[x]=cnt; //根节点
if(sum>cnt) iscut[x]++;
}
if( far && iscut[x]) //非根节点
{
if(!cnt ) iscut[x]=; //没有“是割点”的孩子,那么只要自己是割点,起码可以割为两个连通分量
else if(sum==cnt) iscut[x]=cnt+; //有“是割点”的孩子,那么每个“割点”孩子是1个连通分量,注:有可能还有非割点孩,他们算1个连通分量
else iscut[x]=cnt+;
}
if(iscut[x]) flag=; //无割点的标记'
//if(x==1) cout<<"**"<<sum<<endl; if(!chd && low[x]==dfn[x] ) return true; //返回值用于判断是否是叶子,且没有反向边到fa之上
return false;
} void cal() //n为边数
{ flag=cntr=;
DFS(up,); //深搜求割点数
int i;
for(i=; i<=up; i++) //先确保是个连通图
if(cur[i]&&!vis[i])
{
printf(" No SPF nodes\n");
return ;
} for(i=; i<=up; i++)
if(cur[i]&&iscut[i])
{
printf(" SPF node %d leaves %d subnets\n", i, iscut[i]);
} if(!flag) printf(" No SPF nodes\n");
}
void init()
{
up=;
memset(cur,,sizeof(cur));
memset(mapp,,sizeof(mapp));
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(iscut,,sizeof(iscut)); } int main()
{
freopen("input.txt", "r", stdin);
int j=, a, b;
while()
{
int cnt=;
init();
while(~scanf("%d",&a))
{
if(!a && !cnt) return ; //没边,a又为0,则结束了
if(!a)
{
printf("Network #%d\n",++j);
cal();
printf("\n");break;
}
scanf("%d",&b);
up=max(max(up,a),b); //记录顶点号上限
cur[a]=cur[b]=; //记录出现的顶点号
mapp[a][b]=mapp[b][a]=; //矩阵
cnt++; //边数
}
}
return ;
}
AC代码
POJ 1523 SPF (割点,连通分量)的更多相关文章
- poj 1523 SPF(双连通分量割点模板)
题目链接:http://poj.org/problem?id=1523 题意:给出无向图的若干条边,求割点以及各个删掉其中一个割点后将图分为几块. 题目分析:割点用tarjan算法求出来,对于每个割点 ...
- POJ 1523 SPF 割点 Tarjan
SPF Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9317 Accepted: 4218 Description C ...
- POJ 1523 SPF 割点与桥的推断算法-Tarjan
题目链接: POJ1523 题意: 问一个连通的网络中有多少个关节点,这些关节点分别能把网络分成几部分 题解: Tarjan 算法模板题 顺序遍历整个图,能够得到一棵生成树: 树边:可理解为在DFS过 ...
- Electricity POJ - 2117 + SPF POJ - 1523 去除割点后求强连通分量个数问题
Electricity POJ - 2117 题目描述 Blackouts and Dark Nights (also known as ACM++) is a company that provid ...
- zoj 1119 / poj 1523 SPF (典型例题 求割点 Tarjan 算法)
poj : http://poj.org/problem?id=1523 如果无向图中一个点 u 为割点 则u 或者是具有两个及以上子女的深度优先生成树的根,或者虽然不是一个根,但是它有一个子女 w, ...
- POJ 1523 SPF tarjan求割点
SPF Time Limit: 1000MS Memory Limit ...
- POJ 1523 SPF(求割点)
题目链接 题意 : 找出图中所有的割点,然后输出删掉他们之后还剩多少个连通分量. 思路 : v与u邻接,要么v是u的孩子,要么u是v的祖先,(u,v)构成一条回边. //poj1523 #includ ...
- POJ 1523 SPF (无向图割点)
<题目链接> 题目大意: 给你一个连通的无向图,问你其中割点的编号,并且输出删除该割点后,原图会被分成几个连通分量. 解题分析: Tarjan求割点模板题. #include <cs ...
- poj 1523 SPF(tarjan求割点)
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
随机推荐
- Educational Codeforces Round 13 E. Another Sith Tournament 概率dp+状压
题目链接: 题目 E. Another Sith Tournament time limit per test2.5 seconds memory limit per test256 megabyte ...
- 关于vs2010 起始页
vs2010 起始页不显示怎么解决 工具 ---> 选项---->环境---->启动---->启动时(选项框),然后点击框尾的下拉三角按钮,点选"显示起始页" ...
- [设计模式] 13 责任链模式 Chain of Responsibility
转 http://blog.csdn.net/wuzhekai1985 http://www.jellythink.com/archives/878 向项目经理提交了休假申请,我的项目经理向 ...
- 堆栈中的EIP EBP ESP
EIP,EBP,ESP都是系统的寄存器,里面存的都是些地址. 为什么要说这三个指针,是因为我们系统中栈的实现上离不开他们三个. 我们DC上讲过栈的数据结构,主要有以下特点: 后进先处.(这个强调 ...
- Scrum敏捷开发简介
Agile 敏捷开发实践中,强调团队的自我管理.在 Scrum 中,自我团队管理体现在每天的 Scrum 会议中和日常的协同工作,在每天的 Scrum 例会中,团队成员一般回答一下几个问题 : 昨天完 ...
- 如何用 OneAPM 优化你的 Node.js 应用?
本文主要讲解如何使用 OneAPM 提供的信息从内存.CPU 使用.响应速度等方面优化 Node.js 应用.适用于定位于刚刚使用 Node.js 开发后台的读者.本文系 OneAPM 用户投稿,本网 ...
- 在IDEA上用python来连接集群上的hive
1.在使用Python连接hive之前需要将hive中的文件拷贝到自己创建python项目中 cp -r apache-hive--bin/lib/py /home/jia/Desktop 2.把h ...
- C# 面向对象之概念理解
什么是对象? <韦氏大词典>中对对象定义: (1)某种可为人所感知的物质. (2)思维.感受或动作所作用的物质或精神体. ----说白了万物皆对象 熟悉的对象描述: 对象就是客观世界中的物 ...
- 转: 在.NET中操作数字证书
作者:玄魂出处:博客2010-06-23 12:05 http://winsystem.ctocio.com.cn/19/9492019.shtml .NET为我们提供了操作数字证书的两个主要的类,分 ...
- 李洪强iOS开发之【Objective-C】08-self关键字
一.Java中的this只能用在动态方法中,不能用在静态方法中 1.在动态方法中使用this关键字 1 public class Student { 2 private int age; 3 publ ...