题意:给出一个网络(不一定连通),求所有的割点,以及割点可以切分出多少个连通分量。

思路:很多种情况。

(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 (割点,连通分量)的更多相关文章

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

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

  2. POJ 1523 SPF 割点 Tarjan

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

  3. POJ 1523 SPF 割点与桥的推断算法-Tarjan

    题目链接: POJ1523 题意: 问一个连通的网络中有多少个关节点,这些关节点分别能把网络分成几部分 题解: Tarjan 算法模板题 顺序遍历整个图,能够得到一棵生成树: 树边:可理解为在DFS过 ...

  4. Electricity POJ - 2117 + SPF POJ - 1523 去除割点后求强连通分量个数问题

    Electricity POJ - 2117 题目描述 Blackouts and Dark Nights (also known as ACM++) is a company that provid ...

  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 ...

  7. POJ 1523 SPF(求割点)

    题目链接 题意 : 找出图中所有的割点,然后输出删掉他们之后还剩多少个连通分量. 思路 : v与u邻接,要么v是u的孩子,要么u是v的祖先,(u,v)构成一条回边. //poj1523 #includ ...

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

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

  9. poj 1523 SPF(tarjan求割点)

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

随机推荐

  1. Codeforces Round #327 (Div. 1) B. Chip 'n Dale Rescue Rangers 二分

    题目链接: 题目 B. Chip 'n Dale Rescue Rangers time limit per test:1 second memory limit per test:256 megab ...

  2. 【转载】C#.Net 创建网页快捷方式

    using System.Runtime.InteropServices; using IWshRuntimeLibrary; // 添加引用:COM下Windows Script Host Obje ...

  3. 如何用 OneAPM 优化你的 Node.js 应用?

    本文主要讲解如何使用 OneAPM 提供的信息从内存.CPU 使用.响应速度等方面优化 Node.js 应用.适用于定位于刚刚使用 Node.js 开发后台的读者.本文系 OneAPM 用户投稿,本网 ...

  4. Corner case

    A corner case (or pathological case) is a problem or situation that occurs only outside of normal op ...

  5. PHP图标类库 - JpGraph使用详解

    http://w3note.com/web/181.html 微信平台开发的推广支持应用里,为了满足用户渠道推广分析的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二 ...

  6. POJ3126Prime Path

    http://poj.org/problem?id=3126 题意 : 给你两个四位数,都是素数,一个是初始素数x,一个是目标素数y,让你从x变成y,x每次只能改变1位数,来变成另外一个素数k,再改变 ...

  7. hdu 1329 Hanoi Tower Troubles Again!

    找规律的题目an=an-1+(i+i%2)/2*2; ;}

  8. 【转载】SSH框架总结(将网上朋友写的给整合了下)

    一.Struts 在没有学习SSH框架前,我们一般采用Jsp+javabean+servlet开发,这里就是MVC架构.而Struts其实就是替代了Servlet,我们知道Servlet在一般的开发中 ...

  9. windows下eclipse远程连接hadoop错误“Exception in thread"main"java.io.IOException: Call to Master.Hadoop/172.20.145.22:9000 failed ”

    在VMware虚拟机下搭建了hadoop集群,ubuntu-12.04,一台master,三台slave.hadoop-0.20.2版本.在 master机器上利用eclipse-3.3连接hadoo ...

  10. Play Framework 发现并没有热启动的特殊情况

    解决办法: 删掉 target目录下的两个文件夹: src_mananger 和 twirl -----或者删掉整个target文件夹. 因为play framework 运行的是 在target 文 ...