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 ------------------------------------------------------------ ...
随机推荐
- 【BZOJ】【1770】【Usaco2009 Nov】lights 灯
高斯消元解XOR方程组 一眼看上去是高斯消元解xor方程组……但是不会写……sad 去膜拜了Hzwer和ZYF Hzwer啥也没说,还是zyf靠谱…… 当多解的时候就需要爆搜枚举自由元的情况,找最优解 ...
- UI框架说明
JQueryEasyUI jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面.开发者不需要编 ...
- sampler2d
Here is the syntax for a sampler in Direct3D 9. sampler Name = SamplerType{ Texture = <texture_ ...
- POJ2004 Mix and build Trie树? dp?
学习Trie树中,所以上网搜一下Trie树的题,找到这个,人家写着是简单dp,那我就想着能学习到什么Trie树上的dp,但最后发现根本好像跟Trie树没有什么联系嘛... 题意就是给你很多个字符串(长 ...
- poj 3070 Fibonacci(矩阵快速幂,简单)
题目 还是一道基础的矩阵快速幂. 具体的居者的幂公式我就不明示了. #include<stdio.h> #include<string.h> #include<algor ...
- POJ 3228 Gold Transportation(带权并查集,好题)
参考链接:http://www.cnblogs.com/jiaohuang/archive/2010/11/13/1876418.html 题意:地图上某些点有金子,有些点有房子,还有一些带权路径,问 ...
- POJ 1922
#include<iostream>cheng da cai zi 11.21 //#include<stdio.h> #include<math.h> using ...
- linux内核--进程与线程
http://blog.csdn.net/yusiguyuan/article/details/12154823 在<linux内核设计与实现>中第三章讲解了进程管理,在关于进程和线程的概 ...
- mysql23个知识点
1.它是一种解释语言:写一句执行一句,不需要整体编译执行. 2.1.没有“ ”,字符串使用‘ '包含 3.一个表只有一个主键,但是一个主键可以是由多个字段组成的 组合键 4.实体完整性:实体就是指一条 ...
- 46. Permutations
题目: Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the fo ...