POJ 1523 SPF(无向图割顶)

SPF

Description

Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the still available nodes from communicating with each other. Nodes 1 and 2 could still communicate with each other as could nodes 4 and 5, but communication between any other pairs of nodes would no longer be possible.

Node 3 is therefore a Single Point of Failure (SPF) for this
network. Strictly, an SPF will be defined as any node that, if
unavailable, would prevent at least one pair of available nodes from
being able to communicate on what was previously a fully connected
network. Note that the network on the right has no such node; there is
no SPF in the network. At least two machines must fail before there are
any pairs of available nodes which cannot communicate.

Input

The
input will contain the description of several networks. A network
description will consist of pairs of integers, one pair per line, that
identify connected nodes. Ordering of the pairs is irrelevant; 1 2 and 2
1 specify the same connection. All node numbers will range from 1 to
1000. A line containing a single zero ends the list of connected nodes.
An empty network description flags the end of the input. Blank lines in
the input file should be ignored.

Output

For each network in the input, you will output its number in the file, followed by a list of any SPF nodes that exist.

The first network in the file should be identified as "Network #1",
the second as "Network #2", etc. For each SPF node, output a line,
formatted as shown in the examples below, that identifies the node and
the number of fully connected subnets that remain when that node fails.
If the network has no SPF nodes, simply output the text "No SPF nodes"
instead of a list of SPF nodes.

Sample Input

1 2
5 4
3 1
3 2
3 4
3 5
0

1 2
2 3
3 4
4 5
5 1
0

1 2
2 3
3 4
4 6
6 3
2 5
5 1
0

0

Sample Output

Network #1
  SPF node 3 leaves 2 subnets

Network #2
  No SPF nodes

Network #3
  SPF node 2 leaves 2 subnets
  SPF node 3 leaves 2 subnets
  1 #include<cstdio>
  2 #include<vector>
  3 #include<cstring>
  4 using namespace std;
  5
  6 vector<int>G[1005];
  7 bool flag;
  8 int low[1005],dfs_clock,pre[1005];
  9 bool iscut[1005];
 10 bool vis[1005];
 11
 12 void init()
 13 {
 14     memset(iscut,0,sizeof(iscut));
 15     memset(pre,0,sizeof(pre));
 16     memset(vis,0,sizeof(vis));
 17     for(int i=0;i<1005;i++)G[i].clear();
 18     dfs_clock=0;
 19     flag=0;
 20 }
 21
 22 int findcut(int u,int fa)
 23 {
 24     int lowu=pre[u]=++dfs_clock;
 25     int child=0;
 26     for(int i=0;i<G[u].size();i++)
 27     {
 28         int v=G[u][i];
 29         if(!pre[v])
 30         {
 31             child++;
 32             int lowv=findcut(v,u);
 33             lowu=min(lowu,lowv);
 34             if(lowv>=pre[u])
 35             iscut[u]=true;
 36         }
 37         else if(pre[v]<pre[u]&&v!=fa)
 38         lowu=min(lowu,pre[v]);
 39     }
 40     if(fa<0&&child==1)iscut[u]=0;
 41     low[u]=lowu;
 42     return lowu;
 43 }
 44
 45 void dfs(int u)
 46 {
 47     vis[u]=1;
 48     for(int i=0;i<G[u].size();i++)
 49     if(!vis[G[u][i]])
 50     {
 51         vis[G[u][i]]=1;
 52         dfs(G[u][i]);
 53     }
 54 }
 55
 56 void output()
 57 {
 58     for(int i=1;i<1005;i++)
 59     {
 60         if(iscut[i])
 61         {
 62             flag=1;
 63             memset(vis,0,sizeof(vis));
 64             vis[i]=1;
 65             int son=0;
 66             for(int j=0;j<G[i].size();j++)
 67             {
 68                 if(!vis[G[i][j]])
 69                 {
 70                     dfs(G[i][j]);
 71                     son++;
 72                 }
 73             }
 74             printf("  SPF node %d leaves %d subnets\n",i,son);
 75         }
 76     }
 77     if(!flag)
 78     printf("  No SPF nodes\n");
 79     printf("\n");
 80 }
 81
 82 int main()
 83 {
 84     //freopen("in.txt","r",stdin);
 85     int u,v,t;
 86     bool key=0;
 87     t=0;
 88     while(scanf("%d",&u))
 89     {
 90         if(u==0&&key)
 91         break;
 92         else if(u==0&&!key)
 93         {
 94             printf("Network #%d\n",++t);
 95             findcut(1,-1);
 96             output();
 97             init();
 98             key=1;
 99             continue;
100         }
101         if(u!=0)key=0;else key=1;
102         scanf("%d",&v);
103         G[u].push_back(v);
104         G[v].push_back(u);
105     }
106     return 0;
107 }
时间: 2024-10-08 00:38:19

POJ 1523 SPF(无向图割顶)的相关文章

poj 1523 SPF 无向图求割点

SPF Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the s

POJ 1144 Network【割顶】

学习的这一篇:https://www.byvoid.com/blog/biconnect 割顶:对于无向图G,如果删除某个点u后,连通分量数目增加,称u为图的关节点或者割顶 u为割顶的条件: (1)u不为树根,以u的任一子节点为根的子树中没有一个点有返回u的祖先的反向边(返祖边) (2)u为树根,且u有多于一个子树 紫书上有证明 即为,祖先与每一棵子树之间都有返祖边的话(即,删除u点之后,以v为根的整棵子树都可以通过这条返祖边连回到f),该点不是割顶,如果祖先与它的其中一棵子树缺少返祖边的话,那

POJ 1523 SPF(强连通分量求割点)

题目地址:POJ 1523 这题猛的一看..貌似有点难的样子.不过仔细一想,那个每个割点所分成一次子图不就都能找到这个割点一次吗,那么只要记录下它作为割点的次数再+1不就行了.也算是求割点的裸题吧.这个题的输出很坑...需要注意一下.. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

2018/2/11 每日一学 无向图割顶和桥

割顶和桥:对于无向图G,如果删除某个节点u后,连通分量数目增加,则称u为图的割顶:如果删除某条边后,连通分量数目增加,则称该边为图的桥. 对于连通图删除割顶或桥后都会使得图不再连通. 我们利用dfs的性质来快速找出一个连通图中的所有的割顶和桥. 设low[u]为u及其后代所能连回的最早的祖先的pre[]值,pre[]为时间戳则当u存在一个子节点v使得low[v] >= pre[u]时u就为割顶 同理当 low[v] > pre[u]时 u-v为桥 看代码吧(转自http://blog.csdn

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

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7246   Accepted: 3302 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

poj 1523 SPF

SPF http://poj.org/problem?id=1523 Time Limit: 1000MS   Memory Limit: 10000K       Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a fail

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

题意: 给个无向图,问有多少个割点,对于每个割点求删除这个点之后会产生多少新的点双联通分量 题还是很果的 怎么求割点请参考tarjan无向图 关于能产生几个新的双联通分量,对于每个节点u来说,我们判断他是否是割点,即判断是否满足他的儿子v的low[v]>dfn[u] 而这个时候割掉这个点就会让双联通分量增加,所以搞一个数组记录一下这个操作的次数就行 请注意在是否是根节点的问题上特判 !!注意输出格式!! 1 #include<cstdio> 2 #include<algorithm

POJ 1523 SPF 解题报告

思路:使用tarjan算法求出割点,在枚举去掉每一个割点所能形成的联通块的个数. 注意:后来我看了下别的代码,发现我的枚举割点的方式是比较蠢的方式,我们完全可以在tarjan过程中把答案求出来,引入一下讨论: 如果这个割点是根节点,在tarjan算法中搜到几个孩子结点(low[v] >= dfn[u]),他就能割出几个联通块,如果这个割点是孩子结点,那么他所形成的联通块的个数+1,因为他还有一条与父亲结点间接或直接相连的边. 代码如下: #include<map> #include<

POJ - 1523 SPF(割点)

题目大意:给出一张图,问去割点后,连通分量的个数有多少 解题思路:割点的水题,套模版就可以 不得不吐槽一下输入.. #include <cstdio> #include <cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define N 1010 #define M 2000010 struct Edge{ int to, next; }E[M]; int head[N], num[N], pre[N], lowlink[N]; in