思路:使用tarjan算法求出割点,在枚举去掉每一个割点所能形成的联通块的个数。

  注意:后来我看了下别的代码,发现我的枚举割点的方式是比较蠢的方式,我们完全可以在tarjan过程中把答案求出来,引入一下讨论:

  如果这个割点是根节点,在tarjan算法中搜到几个孩子结点(low[v] >= dfn[u]),他就能割出几个联通块,如果这个割点是孩子结点,那么他所形成的联通块的个数+1,因为他还有一条与父亲结点间接或直接相连的边。

  代码如下:

#include<map>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define maxn 1010
struct EDGE
{
int to,nxt;
} edge[maxn*];
int head[maxn],low[maxn],dfn[maxn],mark[maxn],vis[maxn];
int tot,all,son,start,tail;
void add_edge(int u,int v)
{
edge[tot].to = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
void init()
{
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(mark,,sizeof(mark));
all = ;
son = ;
}
void tarjan(int u,int fa)
{
dfn[u] = low[u] = ++all;
for(int i = head[u]; i != -; i = edge[i].nxt)
{
int v = edge[i].to;
if(!dfn[v])
{
tarjan(v,u);
low[u] = min(low[v],low[u]);
if(low[v] >= dfn[u])
{
if(u == start) son++;
else mark[u] = ;
}
}
else if(v != fa) low[u] = min(low[u],dfn[v]);
}
return ;
}
void bfs(int x,int cant)
{
queue<int>que;
while(!que.empty()) que.pop();
que.push(x);
vis[x] = ;
while(!que.empty())
{
int num = que.front();
que.pop();
for(int i = head[num]; i != -; i = edge[i].nxt)
{
int v = edge[i].to;
if(v != cant && !vis[v])
{
que.push(v);
vis[v] = ;
}
}
}
return ;
}
int main()
{
int a,b;
int ca = ;
while(~scanf("%d",&a))
{
if(!a) break;
start = ,tail = ;
scanf("%d",&b);
start = min(a,b);
tail = max(a,b);
tot = ;
memset(head,-,sizeof(head));
add_edge(a,b);
add_edge(b,a);
while(~scanf("%d",&a))
{
if(!a) break;
scanf("%d",&b);
add_edge(a,b);
add_edge(b,a);
start = min(min(a,b),start);
tail = max(max(a,b),tail);
}
init();
tarjan(start,-);
if(son >= ) mark[start] = ;
int subnets = ,spf = ;
printf("Network #%d\n",++ca);
bool flag = true;
for(int i = start; i <= tail; i++)
{
if(mark[i])
{
flag = false;
printf(" SPF node %d leaves ",i);
memset(vis,,sizeof(vis));
subnets = ;
for(int j = start;j <= tail;j++)
{
if(j == i) continue;
if(!vis[j])
{
subnets++;
bfs(j,i);
}
}
printf("%d subnets\n",subnets);
}
}
if(flag) puts(" No SPF nodes");
puts("");
}
return ;
}

POJ 1523 SPF (去掉割点能形成联通块的个数)的更多相关文章

  1. poj 1523 SPF 求割点以及删除该割点后联通块的数量

    SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7136   Accepted: 3255 Description C ...

  2. POJ 1523 SPF 求割点的好(板子)题!

    题意: 给个无向图,问有多少个割点,对于每个割点求删除这个点之后会产生多少新的点双联通分量 题还是很果的 怎么求割点请参考tarjan无向图 关于能产生几个新的双联通分量,对于每个节点u来说,我们判断 ...

  3. POJ 1523 SPF (无向图割点)

    <题目链接> 题目大意: 给你一个连通的无向图,问你其中割点的编号,并且输出删除该割点后,原图会被分成几个连通分量. 解题分析: Tarjan求割点模板题. #include <cs ...

  4. C. Learning Languages 求联通块的个数

    C. Learning Languages 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring&g ...

  5. zoj 1119 / poj 1523 SPF (典型例题 求割点 Tarjan 算法)

    poj : http://poj.org/problem?id=1523 如果无向图中一个点 u 为割点 则u 或者是具有两个及以上子女的深度优先生成树的根,或者虽然不是一个根,但是它有一个子女 w, ...

  6. POJ 1523 SPF 割点 Tarjan

    SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9317   Accepted: 4218 Description C ...

  7. poj 1523 SPF【点双连通求去掉割点后bcc个数】

    SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7246   Accepted: 3302 Description C ...

  8. poj 1523 SPF(双连通分量割点模板)

    题目链接:http://poj.org/problem?id=1523 题意:给出无向图的若干条边,求割点以及各个删掉其中一个割点后将图分为几块. 题目分析:割点用tarjan算法求出来,对于每个割点 ...

  9. 【POJ】1523 SPF(割点)

    http://poj.org/problem?id=1523 太弱... too weak.. 割点我都还要看书和看题解来写..果然是写不出么.. 割点就那样求,然后分量直接这个节点有多少子树就有子树 ...

随机推荐

  1. vultr vps2016年免费升级流量和cpu

    拥有超高性价比的vultr vps在2016年第一天宣布全面升级vps产品: 悉尼.东京机房vps全部免费升级到北美和欧洲机房相同流量.这就意味着,东京机房vps流量,以1024 MB内存的套餐为例, ...

  2. Openjudge-计算概论(A)-计算三角形面积

    描述: 平面上有一个三角形,它的三个顶点坐标分别为(x1, y1), (x2, y2), (x3, y3),那么请问这个三角形的面积是多少. 输入输入仅一行,包括6个单精度浮点数,分别对应x1, y1 ...

  3. js怎么判断浏览器类型

    <script type=“text/javascript”> function isIE(){return navigator.appName.indexOf(“Microsoft In ...

  4. Sql CE 数据库编程

    用户工具: http://www.linqpad.net/ 查询编辑数据 http://sqlcequery.codeplex.com/  查询编辑数据 开发人员工具: 安装:EF Tools nug ...

  5. Oracle数据库插入数据出错:ORA-06550

    wpf应用调用oracle的存储过程,出错“ORA-06550:参数个数或参数类型出错”,如下图: 反复检查,存储过程的参数个数和参数类型都没错,觉得非常蹊跷.最后终于解决, 原因是当参数的值为nul ...

  6. div盒子水平垂直居中的方法

    这个问题比较老,方法比较多,各有优劣,着情使用. 一.盒子没有固定的宽和高 方案1.Transforms 变形 这是最简单的方法,不仅能实现绝对居中同样的效果,也支持联合可变高度方式使用.内容块定义t ...

  7. [原]innerText与innerHTML区别

    window.onload = function () {             document.getElementById('btn1').onclick = function () {    ...

  8. getuid和geteuid的区别

    getuid() :  函数返回一个调用程序的真实用户ID.表明当前运行位置程序的执行者. geteuid(): 函数返回返回一个有效用户的ID.(EUID)是你最初执行程序时所用的ID,该ID是程序 ...

  9. Android数据库--Sqlcipher的使用(二)

    1.使用Sqlcipher对数据库加密,并结合ORM框架LitePal进行使用. 2.对LitePal的使用我就不在讲解了,大家可以参考下面七篇博客: http://blog.csdn.net/guo ...

  10. Linux raid信息 查看

    Linux下查看软.硬raid信息的方法. 软件raid:只能通过Linux系统本身来查看 cat /proc/mdstat 可以看到raid级别,状态等信息. 硬件raid: 最佳的办法是通过已安装 ...